rails save! create! update!のバリデーション例外を捕捉する

More than 3 years have passed since last update.


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