3. バリデーション(1)
2012/09/24 シナジーマーケティング(株) 寺岡 佑起
Model 3章 バリデーション
3.1. バリデーションとは
3.2. バリデーションの定義
3.3. バリデーションの実行タイミング
3.4. バリデーションエラーの確認
3.5. ビューへの表示
3.6. 組み込みのバリデーション
3.7. 共通のバリデーションオプション
3.8. 独自ロジックでのバリデーション
3.9. カスタムバリデータの作成
3.1. バリデーションとは
バリデーションとは、入力された値がアプリケーションで決められたルールに従っているか検証することを指します。
アプリケーションは、入力値がアプリケーションの仕様上許容される文字数を超えていないか、
メールアドレスが有効なフォーマットで入力されているかなどを検証する必要があるでしょう。
Railsアプリケーションでは、モデルクラスに対してバリデーションを定義することで、入力値の検証を行います。
コントローラのアクションメソッド内で入力値の検証を行うこともできますが、
モデル単位で守られるべき制約は、必ずモデルのバリデーションとして実装するようにしましょう。
モデル単位でのバリデーションを行うことで、どのコントローラから登録されたデータも、
定義された制約が守られていることが保証されます。
3.2. バリデーションの定義
Active Recordでバリデーションの定義を行う場合、validatesクラスメソッドを使用します。
validatesメソッドの引数には検証したいフィールド名を与え、どんな検証をするかや、検証を行う条件などのオプションをハッシュで与えます。
#app/models/employee.rb class Employee < ActiveRecord::Base validates :name, :presence => true # 名前は必須 validates :employee_number, :numericality => {:only_integer => true}, :allow_blank => true # 社員番号は任意の整数値 end
validatesメソッドでは必須チェックや数値チェックなど、複数の種類の検証を一度に定義することができます。
class Employee2 < ActiveRecord::Base validates :name, :presence => true # 名前は必須 # 社員番号は一意な整数値(必須) validates :employee_number, :presence => true, :uniqueness => true, :numericality => {:only_integer => true} end
これは以下の指定と同じ結果になります。
class Employee3 < ActiveRecord::Base validates :name, :presence => true # 名前は必須 # 社員番号は一意な整数値(必須) validates :employee_number, :presence => true validates :employee_number, :uniqueness => true validates :employee_number, :numericality => {:only_integer => true} end
また、以下のように複数のフィールドに対して一度に検証を定義することもできます。
class Employee4 < ActiveRecord::Base # 名前、社員番号は必須かつ2~10文字 validates :name, :employee_number, :presence => true, :length => (2..10) end
3.3. バリデーションの実行タイミング
モデルクラスに定義されたバリデーションは、オブジェクトの保存前に自動的に実行されます。
saveメソッドが呼び出されると、最初にモデルクラスに定義されたバリデーションが実行されます。
検証に成功した場合、データベースへの登録、更新処理が実行され、戻り値としてtrueが返されます。
1フィールドでも検証に失敗するとデータベースへの登録、更新処理は実行されず、戻り値はfalseを返します。
3.2のEmployeeクラスを利用した以下のコードで確認することができます。
employee = Employee.new # nameが設定されていないため検証エラーになる employee.save # false # データベースに保存されていないためnew_record?はtrueになる employee.new_record? # true employee.name = 'taro' employee.employee_number = 15 # name、employee_numberが正しく設定されているため検証エラーにならない employee.save # true # データベースに保存されたためnew_record?はfalseになる employee.new_record? # false
バリデーションは以下の登録、更新を行うメソッドを呼び出した際に自動的に実行されます。
以下のうち末尾に!がつくメソッドはバリデーションの検証に失敗した場合、ActiveRecord::RecordInvalid例外がraiseされます。
- create
- create!
- save
- save!
- update
- update_attributes
- update_attributes!
以下にあげるようなメソッドはバリデーションを実行せずにデータベースに保存します。
このようなメソッドを利用する場合、バリデーションが実行されないため、予期せぬデータを保存してしまう可能性があるので十分に注意して利用しましょう。
- decrement!
- decrement_counter
- increment!
- increment_counter
- toggle!
- touch
- update_all
- update_attribute
- update_column
- update_counters
また、saveメソッドでは以下のようにvalidateオプションをfalseに設定することでバリデーションをスキップすることができます。
このオプションを指定する場合も保存されるデータに注意が必要です。
employee = Employee.new employee.save(:validate => false)
データベースへの保存を行わずに、データの検証処理のみを実行したい場合もあるでしょう。
valid?、invalid?メソッドを呼び出すことで、モデルのデータを保存せずに、バリデーションのみを実行することができます。
valid?メソッドは、検証に成功した場合にtrue、いずれかの検証に失敗した場合にfalseを返します。
invalid?メソッドはvalid?メソッドの逆で、検証を実行し、成功した場合にfalse、失敗した場合にtrueを返します。
employee = Employee.new if employee.valid? # 検証に成功した場合の処理... end