3. バリデーション(4)
2012/09/25 シナジーマーケティング(株) 寺岡 佑起
Model 3章 バリデーション
3.1. バリデーションとは
3.2. バリデーションの定義
3.3. バリデーションの実行タイミング
3.4. バリデーションエラーの確認
3.5. ビューへの表示
3.6. 組み込みのバリデーション
3.7. 共通のバリデーションオプション
3.8. 独自ロジックでのバリデーション
3.9. カスタムバリデータの作成
3.7. 共通のバリデーションオプション
前項(3.6. 組み込みのバリデーション )で紹介したバリデーション定義に対して、共通して利用できるオプションがあります。
:allow_nil
:allow_nilオプションにtrueを指定すると、検証対象の値がnilの場合にバリデーションがスキップされ、エラーが発生しません。
:allow_blank
:allow_nilオプションと似ていますが、こちらは検証対象の値がblank?(nilや空文字の場合)にバリデーションをスキップします。
:message
:messageオプションには検証失敗時のエラーメッセージを指定することができます。
このオプションを指定しない場合、各バリデーションで定義されたのデフォルトのメッセージが利用されます。
:on
:onオプションはバリデーションの実行タイミングを指定します。
バリデーションが定義され、saveメソッドが呼び出されると、レコードが新規、更新どちらの状態でも常に実行されます。
:onオプションを指定されたバリデーションは、:createを指定すると新規作成時のみ、:updateを指定すると更新時のみ実行されるようになります。
:if
:ifオプションを指定することで、バリデーションを実行する条件を任意に制御することができます。
:ifオプションにはシンボル、文字列、Procオブジェクトを指定することができます。
■ シンボルで指定する場合
指定した名前のモデルクラスのメソッドが実行され、実行されたメソッドの戻り値がtrueの場合に対象のバリデーションが実行されます。
class Person < ActiveRecord::Base STATUS_TEMPORARY = 1 STATUS_MEMBER = 2 validates :email, :presence => true, :if => :member? def member? self.status == STATUS_MEMBER end end
■ 文字列で指定する場合
指定した文字列がevalされ、実行結果がtrueの場合に対象のバリデーションが実行されます。
この指定は短く書きたい場合に有効ですが、あまりおすすめできません。
文字列のevalはセキュリティホールになりやすく、可能な場合は別の手段で実装すべきでしょう。
class Person < ActiveRecord::Base STATUS_TEMPORARY = 1 STATUS_MEMBER = 2 validates :email, :presence => true, :if => "self.status == STATUS_MEMBER" end
■ Procオブジェクトで指定する場合
指定したProcオブジェクトが実行され、実行結果がtrueの場合に対象のバリデーションが実行されます。
Procオブジェクトの実行時には、第一引数に対象レコードのオブジェクトが渡されます。
また、モデルオブジェクトがselfとなるように実行されるため、引数を利用せずに対象モデルのメソッドにアクセスすることができます。
class Person < ActiveRecord::Base STATUS_TEMPORARY = 1 STATUS_MEMBER = 2 validates :email, :presence => true, :if => Proc.new {self.status == STATUS_MEMBER} end
:unless
:ifオプションと同様に、シンボル、文字列、Procオブジェクトを指定することができます。
:ifオプションと違って、指定された条件が偽(falseまたはnil)となる場合に対象のバリデーションが実行されます。
上記で紹介したオプションのうち、:allow_nil, :allow_blank, :on, :if, :unless はvalidatesメソッド利用時に、複数のバリデーションに対して同時に設定することができます。
そのため、下記の2つの定義は同じ意味を持ちます。
validates :password, :presence => {:if => :password_required?}
validates :password, :presence => true, :if => :password_required?