Goal
save!
/ create!
/ update!
メソッドでバリデーションエラー・コールバックエラーを例外ハンドリングできるようにして、なおかつエラー内容を知りたい.
以下のコードはpersonが作られる前に例外発生するため機能しない.
##
## 機能しません!!!
##
def create
@person = Person.create!({ name: "Isaac Newton", age: 35 })
rescue ActiveRecord::RecordInvalid
pp @person.errors # personに値が代入される前にcreate!は例外を投げるためpersonは空になってしまう
end
Code
validationエラー時に投げられるActiveRecord::RecordInvalidオブジェクトがバリデーションエラー情報を持っているのでこれを使えばいい.
http://api.rubyonrails.org/classes/ActiveRecord/RecordInvalid.html#method-c-new
def create
@person = Person.create!({ name: "Isaac Newton", age: 35 })
rescue ActiveRecord::RecordInvalid => e
pp e.record.errors
end
save!
/ create!
/ update!
はモデル層のエラーを例外として返し、save
/ create
/ update
は返り値falseで返す.
モデル層のエラーとはvalidationとcallback. その他のSQLエラーやDB通信エラーなどインフラ層と考えられるエラーは!ありでもなしでも例外として投げられる.
http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-save-21
save,create,update | save!,create!,update! | |
---|---|---|
ActiveRecord::RecordInvalid(validation系) | return false | 例外 |
ActiveRecord::RecordNotSaved(callback系) | return false | 例外 |
ActiveRecord::RecordNotUnique,ActiveRecord::StatementInvalidなど | 例外 | 例外 |
Environment
% bundle exec rails -v
Rails 4.1.9