Rails カスタムバリデーション(validator, EachValidator)


はじめに

今回はカスタムバリデーションについて、まとめれればと思います。

カスタムバリデーター

モデルとは別で、自分でバリデータやバリデーションメソッドを作成することができます。app/配下にvalidatorsディレクトリ(app/validators)を作成することで、自動で読み込んでくれます。

validator

ActiveModel::Validatorを継承するクラス。このクラスでは、validateメソッドを実装する必要があります。
クラス名に規定はなく、validateメソッドを実装する必要があり、
引数としてrecordを受け取ることができます。
このrecordというはの、バリデーション対象のモデルのインスタンスが入ります。


class UserValidator < ActiveModel::Validator
  def validate(record)
    if record.id.present? && !User.exists?(id: record.id)
      record.errors[:name] << '対象のユーザーはいません'
    end
  end
end

呼び出し方法


class User
  include ActiveModel::Validations
  validates_with UserValidator
end

EachValidator

一つの属性に対してのカスタムバリデータを定義できる。ActiveModel::EachValidatorを継承したクラス。

クラス名は<検証名>Validatorの形式で命名。validate_eachメソッドを実装する必要があります。
validate_eachメソッドは引数として(recordattributevalue)の3つを受け取ります。

この引数の3つは
record モデルインスタンス
attribute 属性名
value 属性値

app/validators/user_name_validator.rb


class UserNameValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
      if value.empty? || value.count < 2
          record.errors[:attribute] << (options[:message] || "2文字以上で入力してください")
      end
  end
end

呼び出し方法


validates :name, user_name: true