web-dev-qa-db-ja.com

レール:update_attributeとupdate_attributes

Object.update_attribute(:only_one_field, "Some Value")
Object.update_attributes(:field1 => "value", :field2 => "value2", :field3 => "value3")

これらは両方とも、明示的にARに更新を指示しなくてもオブジェクトを更新します。

Rails APIは言う:

update_attributeの場合

通常の検証手順を実行せずに、単一の属性を更新してレコードを保存します。これは既存のレコードのブーリアンフラグに特に便利です。検証モジュールが混在する場合、Baseの通常のupdate_attributeメソッドはこれに置き換えられます。これはデフォルトです。

update_attributesの場合

渡されたハッシュからすべての属性を更新してレコードを保存します。オブジェクトが無効な場合、保存は失敗し、falseが返されます。

そのため、オブジェクトを検証したくない場合は、update_attributeを使用してください。この更新をbefore_saveで実行した場合、スタックオーバーフローが発生しますか?

私の質問は、update_attributeはbefore saveや単にバリデーションも迂回することです。

また、update_attributesにハッシュを渡すための正しい構文は何ですか...上の例をチェックしてください。

246
thenengah

update_attribute を参照してください。ソース表示をクリックすると、以下のコードが表示されます。

      # File vendor/Rails/activerecord/lib/active_record/base.rb, line 2614
2614:       def update_attribute(name, value)
2615:         send(name.to_s + '=', value)
2616:         save(false)
2617:       end

そして update_attributes を参照して、得られたコードを見てください。

      # File vendor/Rails/activerecord/lib/active_record/base.rb, line 2621
2621:       def update_attributes(attributes)
2622:         self.attributes = attributes
2623:         save
2624:       end

両者の違いは update_attribute uses save(false) に対して update_attributes uses saveNAME _ または save(true) と言うこともできます。

長い説明で申し訳ありませんが、私が言いたいことは重要です。 save(perform_validation = true)perform_validationがfalseの場合、savename__に関連付けられているすべての 検証 は省略されます(スキップは適切なWordになります)。

2番目の質問に

また、update_attributesにハッシュを渡すための正しい構文は何ですか...上の例をチェックしてください。

あなたの例は正しいです。

Object.update_attributes(:field1 => "value", :field2 => "value2", :field3 => "value3")

または

Object.update_attributes :field1 => "value", :field2 => "value2", :field3 => "value3"

あるいは、すべてのフィールドのデータと名前をハッシュで取得する場合は、params[:user]とします。

Object.update_attributes(params[:user])
318
Salil

Tip:update_attributeはRails 4では Commit a7f4b0a1 で非推奨になりました。 update_attributeを優先してupdate_columnを削除します。

74
Matt

update_attribute

このメソッドは、モデルベースの検証を呼び出さずにオブジェクトの単一の属性を更新します。

obj = Model.find_by_id(params[:id])
obj.update_attribute :language, “Java”

update_attributes

このメソッドは単一のオブジェクトの複数の属性を更新し、モデルベースの検証にも合格します。

attributes = {:name => “BalaChandar”, :age => 23}
obj = Model.find_by_id(params[:id])
obj.update_attributes(attributes)

どのような方法でアクティブレコードを使用するかを明確にしてください。

15

update_attributeで指定された属性のみを更新する一括代入メソッドattr_accessibleとは対照的に、update_attributesを使用すると、更新する目的の属性をattr_accessibleでホワイトリストに登録する必要がないことも注目に値します。

11
Kibet Yegon

update_attributeは単にモデルの1つの属性のみを更新しますが、update_attributesメソッドで複数の属性を渡すことができます。

例:

user = User.last

#update_attribute
user.update_attribute(:status, "active")

検証に合格

#update_attributes
user.update_attributes(first_name: 'update name', status: "active")

検証に失敗しても更新されません。

7
Shoaib Malik

素晴らしい答えです。 Ruby 1.9以降ではupdate_attributesに新しいハッシュ構文を使うことができる(そしてそうすべきだと思う)。

Model.update_attributes(column1: "data", column2: "data")
6
Ziv Galili

属性やレコードの更新(Rails 4に更新された)を割り当てるための考えられるすべての方法については、このブログ投稿をご覧ください。update_attribute, update, update_column, update_columns etc.http://www.davidverhasselt.com/set-attributes-in-activerecord/ 。たとえば、検証の実行、オブジェクトのupdated_atの変更、コールバックのトリガなどの点で異なります。

OPの質問に対する答えとして、update_attributeはコールバックを渡しません。

5
adamliesko

update_attributeupdate_attributesは似ていますが、大きな違いが1つあります。update_attributeは検証を実行しません

また:

  • update_attributeは、単一属性でレコードを更新するために使用されます。

    Model.update_attribute(:column_name, column_value1)
    
  • update_attributesは、複数属性でレコードを更新するために使用されます。

    Model.update_attributes(:column_name1 => column_value1, :column_name2 => column_value2, ...)
    

これら2つの方法は、名前と機能が似ているため、非常に混乱しやすいものです。したがって、update_attributeupdate_columnのために削除されています。

さて、Rails4ではModel.update_column(:column_name, column_value)の代わりにModel.update_attribute(:column_name, column_value)を使うことができます。

ここをクリックupdate_columnに関するより多くの情報を得るため。

4
uma

あなたの質問に答えるために、update_attributeはpre-save "validation"をスキップしますが、それはまだ実行しますafter_saveなどのような他のコールバックです。 (どうやら)使用する

Model.update_all(...)を参照してください https://stackoverflow.com/a/7243777/3245

3
rogerdpack

最近、私はupdate_attributeupdate_attributesと検証の問題に遭遇しました。名前が似ているので、振る舞いが違うので、混乱します。

ハッシュをupdate_attributeに渡して検証を迂回するには、次のようにします。

object = Object.new
object.attributes = {
  field1: 'value',
  field2: 'value2',
  field3: 'value3'
}
object.save!(validate: false)
2

あなたの質問は、before_saveにupdate_attributeがあると無限ループ(before_saveコールバック内のupdate_attribute呼び出しの、もともとはupdate_attribute呼び出しによって引き起こされる)につながるかどうかと思います。

実際にはレコードが保存されないので、before_saveコールバックをバイパスすることは間違いありません。を使用して検証をトリガーせずにレコードを保存することもできます。

Model.save false

1
concept47