このエントリーをはてなブックマークに追加

2016年12月27日火曜日

Railsのバリデーション

こんにちは、h_ono_222です。
今回はRailsのvalidationについて簡単にまとめます。

目次

  1. 基本的なバリデーション
  2. EachValidatorクラス
  3. Validatorクラス
  4. autoload_pathsの編集

基本的なバリデーション

ある属性に必ず値が入っていること、何文字以内であることなど、一つの属性に対するバリデーションは下記のように行えます。
# app/models/user.rb(会員モデル)
class User < ActiveRecord
  # 名前がnullでなく15文字以内であること
  validates :name, presence: true, length: { maximum: 15 }

  # 会員IDがnullでなく10文字以内でユニークであること
  validates :user_code, presence: true, length: { is: 10 }, uniqueness: true

  # 年齢が10歳以上20歳未満であること
  validates :age, presence: true,
      numericality: {
        greater_than_or_equal_to: 10,
        less_than: 20
      }

  # 性別がnullでないこと
  validates :gender, presence: true
end

EachValidatorクラス

EachValidatorクラスを継承したクラスを定義すると、一つの属性に対して新しい検証ルールを追加することができます。
# lib/validators/email_validator.rb
class EmailValidator < ActiveModel::EachValidator
  # EachValidatorではvalidate_eachというメソッドを定義する必要が有る
  def validate_each(record, attribute, value)
    # errorsに値を入れることでバリデーション失敗としている
    record.errors.add attribute, 'error message' if value.end_with?('@hoge.com')
  end
end

# app/models/user.rb(会員モデル)
class User < ActiveRecord
  # ActiveRecord::baseを継承していない場合は、下記のモジュールをincludeする
  # include ActiveModel::Validations

  # 中略…

  # 引数として渡された(この場合はemail:)ハッシュのキーに応じたEachValidatorが利用される
  # この場合はEmailValidatorが利用される
  validates :email, presence: true, email: true
end

Validatorクラス

Validatorクラスを継承したクラスを定義すると、複数の属性が絡むような複雑な検証ルールを定義できます。
# lib/validators/member_registration_validator
class MemberRegistrationValidator < ActiveModel::Validator
  # validateメソッドを定義する必要がある
  def validate(record)
    # enum gender: { male: 1, female: 2 }
    if record.age < 20 and record.male?
      record.errors.add :base, 'error message1'
    elsif record.age < 18 and record.female?
      record.errors.add :base, 'error message2'
    end
  end
end

# app/models/user.rb
class User < ActiveRecord
  # 省略…
  validate_with MemberRegistrationValidator
end

autoload_pathsの編集

今回はバリデーションクラスをlib/validator/以下のディレクトリに配置しました。
このディレクトリはそのままでは読み込まれないので、config/application.rbを修正します。
# config/application.rb
module TestApp
  class Application < Rails::Application
    # カスタムバリデータ用ディレクトリ
    config.autoload_paths += %W(#{config.root}/lib/validators)
  end
end

0 件のコメント:

コメントを投稿