はじめに
バリデーションの作成方法はモデル内にprivateメソッドを作って、そのメソッドをvalidateの引数に指定する方法が一般的かと思います。
今回は、複数のモデルで同じバリデーションを適用したいケースへの対応方法をまとめました。
独自バリデーション作成方法
やること
開始日時カラムと終了日時カラムを持ったモデルの入力フォームに、
どちらのカラムも入力するか、どちらのカラムも入力しないバリデーションをかけたい。
Concern
まずは、app/models/concerns
の直下にバリデーション専用のクラスを作成する。
Concernsを使用することで、同じカラムを持った他のモデルにも適用することができ、さらに細かい継承関係を考えなくてもよくなります。
app/models/concerns/work_datetime_validation.rb
class WorkDatetimeValidation < ActiveModel::Validator
# record には、インスタンスが入る
def validate(record)
return if record.work_datetime_begin && record.work_datetime_end
return if !record.work_datetime_begin && !record.work_datetime_end
record.errors[:base] << '開始日時と終了日時どちらも入力するか、どちらも空にしてください'
end
end
Model
次にModelにvalidates_with
を用いて、先ほど作成したクラスを指定する。
他のModelにも適用させたい場合は、validates_with
を他のクラスに書けばバリデーションが適用されます。
app/models/work.rb
class Work < ApplicationRecord
validates_with WorkDatetimeValidation
end
以上となります。
まとめ
時間に関するバリデーションは複数のモデルで使用したいというニーズがあると思いますので、ぜひ活用してみてください。