web-dev-qa-db-ja.com

save!、create!を使用する場合およびupdate_attributes! Railsで?

私は強打を使用するタイミングを把握しようとしています!レコードを保存および更新するためのバージョン? 1つのレコードを保存する場合や1つの属性を更新する場合、何も問題が発生しないと確信している場合、またはそれらを常にコントローラーの外部で使用する場合は、これらのファイルは必要ないと読みました。私は複数のものを保存してから何かが失敗し、DBに不完全なデータが存在することについて妄想していると思います。現在作業中のRailsプロジェクトは50%以上完了しており、現在、前髪は含まれていません。複数のレコードを更新または作成するモデルで呼び出すカスタムメソッドがいくつかあり、何らかのトランザクションを行う必要があるかどうかを心配します。

これが散在しているように思われる場合は申し訳ありませんが、ActiveRecordの保存機能を正しく使用し、最終的にはストレスを軽減し、生活を楽にする方法を考えています。御時間ありがとうございます。

60
CalebHC

一般に、コントローラーで非バングバージョンを使用する必要があります。これにより、次のようなロジックが可能になります。

def update
  @model = Model.find params[:id]
  if @model.update_attributes params[:model] #returns true of false
     # handle success
  else
     # handle failure
  end
end

何かが検証されず、保存されていないかどうかを確認したいとき、私はテストで強打バージョンを多く使用しています。モデルの検証が変更されたために失敗したテストのデバッグに時間を無駄に費やしましたが、これはバングバージョンを使用した場合には明らかです。

例えば.

it "should do something" do
   m = Model.create! :foo => 'bar' # will raise an error on validation failure             
   m.should do_something
end

データベースに無効なデータがないことに関しては、ActiveRecord検証でこれを処理する必要があります(例:validates_presence_of :user_id)、またはモデルで独自のvalidateメソッドを定義します。 ( http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html )これにより、データが有効でない場合に保存が行われないようにする必要があります。本当に妄想している場合は、データベースにいくつかの制約を追加できます。 ActiveRecord::Migration移行で一意のインデックスおよびその他のデータベースの制約を設定する方法に関するドキュメント。

また、私の経験では、可能な限りカスタムのsaveメソッドまたはcreateメソッドの使用を避けたいと考えています。 ActiveRecordに含まれる機能を再実装すると、将来的に価格を支払うことになります。 http://matthewpaulmoore.com/post/5190436725/Ruby-on-Rails-code-quality-checklist でこれについて詳しく説明します。

51
samg

主な違いは、失敗した保存の処理方法です。 ActiveRecordクラスを更新する場合、!バージョンは、レコードが無効な場合に例外を発生させます。

ここでドキュメントを読むことをお勧めします- http://api.rubyonrails.org/classes/ActiveRecord/Base.html

トランザクションを使用することも検討する価値があるかもしれません- http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html

76
Andy Gaskell

何! (bang)はupdate_attributesおよびsaveの意味:

「失敗時にfalseを返す」ではなく、「失敗時に例外を発生させる」

https://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-update-21https://api.rubyonrails.org/classes/ActiveRecord/ Persistence.html#method-i-save

何! (bang)createの意味は:

「失敗時に結果オブジェクトを返す」ではなく「失敗時に例外を発生させる」 https://api.rubyonrails.org/classes/ActiveRecord/Persistence/ClassMethods.html#method-i-create-21 =

3
Tim Heilman