継続的ブロギング

今度こそは続けるブログ

メールアドレスの取り扱いについて改めて調べてみた

メールアドレスの大文字小文字を区別するか、しないとかとかの話。
結局Railsではどう実装するのがいいのだろうか気になったので改めて調べてみました。

メールアドレスの大文字小文字は区別されないと考えて良い

  • メールサーバーの設定によるが、実際には区別しない設定にしているところが大半
  • 正確には、ドメイン名部分だけが大文字小文字を区別しない

DBによるインデックス管理方法の違い

  • MySQL
    • アルファベットの大文字小文字を区別しない
  • PostgreSQL
    • アルファベットの大文字小文字を区別する
    • lower関数を用いてインデックスを作成すれば、アルファベットの大文字小文字を区別しないようにできるが、Railsの標準的なやり方では関数を含むインデックスは作成できない

基本的には小文字に変換して登録しちゃってOK

上記のことから、小文字で登録するのが良さそう。
emailカラム一つだけ用意して、そこに小文字変換で登録していくスタイル。
Railsチュートリアル」でもそう。

今読んでいる『実践Ruby on Rails 4』ではemail_for_indexというカラムを別途用意していました。
emailカラムにはメールアドレスそのものを、email_for_indexには小文字に変換したメールアドレスを登録します。
登録したそのままのメールアドレスをViewに表示したかったので、今回はこちらを採用。

email_for_indexにインデックス追加
add_index :users, :email_for_index, unique: true

バリデーションすり抜けられた時の為に、UNIQUE制約も同時につけています。

モデルに諸々追加
# 一部抜粋

before_validation do
  self.email_for_index = email.downcase if email
end

validates :email, presence: true, email: { allow_blank: true }
validates :email_for_index, uniqueness: { allow_blank: true }
after_validation do
  if errors.include?(:email_for_index)
    errors.add(:email, :taken)
    errors.delete(:email_for_index)
  end
end

after_validationでは、HTMLフォームでemail属性に対して入力エラーメッセージを表示するために、エラーが起きている属性を入れ替えています。
errors.addの第二引数の:takenはuniquenessタイプのシンボルです。

参考

オススメ

もっと早くに出会いたかった。