23
9

More than 5 years have passed since last update.

Railsでメールアドレスのバリデーション

Posted at

Railsでメールアドレスのバリデーション

日本で使われているメールアドレスがRFCに準拠していないので、Railsで現実的な最低限のメールアドレスのフォーマットのバリデーションを追加するケースがよくあると思います。

wtf...email...address...validation...@example.com

上記のようなメールアドレスはRailsのデフォルトのメールアドレスのバリデーションでは弾かれますが、このようなメールアドレスを登録できるようにしましょう。

方針

メールアドレスの@よりも前の部分は雑にASCII印字可能文字(0x20〜0x7E)を許可し、ただしスペース(0x20)と@(0x40)は除きます。正規表現で表すと以下のようになります。

[\x21-\x3f\x41-\x7e]+

メールアドレスの@よりも後の部分は、ドメインですね。正規表現で表すと以下のようになります。

(?:[-a-z0-9]+\.)+[a-z]{2,}

2つの正規表現を@でつなげたのが目的の正規表現です。

[\x21-\x3f\x41-\x7e]+@(?:[-a-z0-9]+\.)+[a-z]{2,}

Railsのカスタムバリデーションを作る

Railsのカスタムバリデーションを作りましょう。

app/lib/validators/email_format_validator.rb
class EmailFormatValidator < ActiveModel::EachValidator
  # メールアドレスの@よりも前には、ASCII印字可能文字のうちスペース(\x20)と@(\x40)以外を許可する
  EMAIL_FORMAT_REGEX = /\A[\x21-\x3f\x41-\x7e]+@(?:[-a-z0-9]+\.)+[a-z]{2,}\z/i

  def validate_each(record, attribute, value)
    record.errors.add attribute, (options[:message] || :invalid_email) unless valid_email?(value)
  end

  private

  def valid_email?(email)
    email =~ EMAIL_FORMAT_REGEX
  end
end

これを、Rails起動時に読み込むようにします。

app/config/application.rb
module Sample
  class Application < Rails::Application
    config.autoload_paths += %W[#{config.root}/lib/validators]
    config.eager_load_paths += %W[#{config.root}/lib/validators]
  end
end

あとはモデルでバリデーションを利用するだけです。

class User < ApplicationRecord
  validates :email, presence: true, email_format: true
end
23
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
9