分けることができない処理を
ActiveRecord::Base.transaction do
end
で囲うのはもちろんとして、
Railsは
ActiveRecord::Base.transaction do
end
で囲っていなくても、DBをコミットしたりロールバックする処理が自動で走るのだが、
後から見て自動で走るポイントがわかりずらいので、明示的に
ActiveRecord::Base.transaction do
end
で囲ったほうがよいかも。
なので、下記のような形にすることがあるかな。
def hoge
ActiveRecord::Base.transaction do
foo.save!
end
ActiveRecord::Base.transaction do
bar.save!
end
rescue ActiveRecord::RecordInvalid
# エラーハンドリング
end
でも、本当は、明示的に囲うのではなく、分けてもよい処理なら
def hoge
unless foo.save
# エラーハンドリング
return
end
unless bar.save
# エラーハンドリング
return
end
end
もありかな。 上記は別のオブジェクトへのsaveが2回以上でてくる例なので、
トランザクションで囲ってrescue ActiveRecord::RecordInvalid
でエラーハンドリングするのか、
unless
でエラーハンドリングするのか悩みどころだが、saveが1個のみなら、
def hoge
unless foo.save
# エラーハンドリング
return
end
end
のunless
形1択で、
def hoge
ActiveRecord::Base.transaction do
foo.save!
end
rescue ActiveRecord::RecordInvalid
# エラーハンドリング
end
とはしないのが普通かな?
eachとかで何回も保存するときは、要件的に分けられない処理と考えられることが多いので、
def hoge
ActiveRecord::Base.transaction do
foos.each do|foo|
foo.save!
end
end
rescue ActiveRecord::RecordInvalid
# エラーハンドリング
end
の形になることが多い気がする。
んー、後からみて自動で走るポイントがわかりずらいと、始めに書いたが、
おそらく、save
かsave!
を何も考えずに書けば、都度コミットが走って、save!
のときはロールバックも走るのだと推測している。