【Rails】saveとsave!について
先日うちの開発メンバーから新人さんに共有があったんですが、
saveとsave!の振る舞いの違いなどについてまとめておきます。
当然のことながら、ActiveRecordでは、モデルオブジェクトの値を変更、保存、削除することができ、対応するレコードの内容を更新することができます。属性の値を変更、保存するメソッドはたくさんありますが、自分が使うところで以下一例です。
save、save!、create、create!、update、update_all、update_attribute、update_attributes、update_attributes!、destroy、destroy_all、delete、delete_all
ActiveRecord::Baseを継承したモデルオブジェクトの属性の変更について、ぽちぽちまとめてみようかなとは思いますが、とりあえず、話に上がったsaveとsave!について(´・ω・`)
まず、saveとsave!の違いは、保存出来なかった場合の振る舞いにあります。
・saveメソッドは、保存できない場合falseを返します。
・save!メソッドは、保存できない場合例外ActiveRecord::RecordInvalidが発生します。
ちなみに、どちらもバリデーションの実行をするので、バリデーションを行わない場合は、
save(:validate => false)またはsave!(:validate => false)でスキップできます。
saveとsave!は一見同じようには見えますが、falseを返すのか例外を発生させるのかの違いから、
それぞれのよく使われる利用シーンは以下のような感じです(´・ω・`)
◯DBに保存できたかどうかによって処理を分岐したい場合
大概saveが使われます。
true、falseが戻ってきてくれればさえ良いので。
@hoge = Hoge.new(:name => "piyo") if @hoge.save p "ゆっくりしていってね!" else p "ぬるぽ" end
例えばこれをあえて、
@hoge = Hoge.new(:name => "piyo") begin @hoge.save! p "ゆっくりしていってね!" rescue p "ぬるぽ" end
と書くと、処理が増えてきた時に追いかけきれなくなります(´・ω・`;)
ただ以下の場合は別です。
◯トランザクション中にデータを保存したい場合
こちらは大概save!が使われます。
transactionメソッドは例外が発生した場合にロールバックするので、保存に失敗したら例外を発生させなくてはいけません。
@hoge = Hoge.new(:name => "piyo") begin Hoge.transaction do @hoge.save! end p "ゆっくりしていってね!" rescue p "ぬるぽ" end
◯コンソールからデータを操作、更新する
これはもう別にsaveでもsave!でもどっちでもかまいませんw
お好きなほうでw
あとでまとめようかなとは思いますけど、create!、update_attributes!も同様です。