Railsで(動的に)柔軟にバリデーションを変更する方法
運用上、バリデーションを(動的に)柔軟に変更したいということがある。
例えばパスワードに含まれてもよい記号を追加するとか、10進数だけでなく16進数の入力も許すようにするとか。
validates_...(validates_format_of, ...)はモデルの初期化時(=railsの起動時)にのみバリデーションを定義する。
すなわちvalidates_...で設定用の変数を読み込むようにして、後からその設定用の変数の値を変えても適応されない。
validateメソッド
設定用の変数を使って、動的にバリデーションを変更したいという場合には以下のようにvalidate do~endを使いましょう。
validateメソッドはバリデーションの際に毎回ブロック内のコードが実行されます。
例)名前の正規表現が記述された設定変数(name_config)を使ったバリデーション
validate do
errors.add(:name, :name_error) if name !~ /#{name_config}/
end
補足(別の方法)
Modelに動的にバリデーションを追加する
self.singleton_class.class_eval()を使って、動的にModelにバリデーションを追加できますが、この方法では前回のバリデーションが残ったまま重複してしまいます。
Controllerの#createや#updateでチェックする
それでも良いですが、バリデーションはmodelにまとめた方が分かりやすいかと思います。