Rails: # update_Attribute vs # update_Attribute

obj.update_attribute(:only_one_field, 'Some Value')
obj.update_attributes(field1: 'value', field2: 'value2', field3: 'value3')

这两种方法都可以更新对象,而无需显式地告诉 ActiveRecord 进行更新。

Rails API 表示:

Update _ tribute 更新属性

更新单个属性并保存记录,而不必经过正常的验证过程。这对于现有记录上的布尔标志特别有用。当混合了验证模块(默认情况下是这样)时,Base 中的常规 update _ Attribute 方法将被替换为 this。

Update _ properties 更新属性

更新传入 Hash 中的所有属性并保存记录。如果对象无效,则保存将失败,并返回 false。

因此,如果我不想验证对象,我应该使用 #update_attribute。如果我在 #before_save上有这个更新,它会堆栈溢出吗?

我的问题是 #update_attribute是否也绕过了之前的保存或只是验证。

另外,将散列传递给 #update_attributes的正确语法是什么... ... 请查看顶部的示例。

322117 次浏览

请参考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使用save(false),而update_attributes使用save,或者你可以说save(true)

抱歉描述太长了,但我想说的是重要的。save(perform_validation = true),如果perform_validation为假,它将绕过(跳过将是正确的词)与save相关的所有验证

第二个问题

另外,将哈希传递给update_attributes的正确语法是什么…请查看顶部的示例。

你的例子是正确的。

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

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

或者如果你得到所有字段的数据&params[:user]在这里使用just

Object.update_attributes(params[:user])

我认为你的问题是,如果在before_save中有一个update_attribute将导致无休止的循环(在before_save回调中调用update_attribute,最初由update_attribute调用触发)

我很确定它确实绕过了before_save回调,因为它实际上并不保存记录。还可以在不触发验证的情况下保存记录

模型。保存错误

提示: update_attribute在Rails 4中通过提交a7f4b0a1被弃用。它删除了update_attribute,改为update_column

同样值得注意的是,使用update_attribute,需要更新的属性不需要用attr_accessible作为白名单来更新它,这与质量分配方法update_attributes相反,后者只更新attr_accessible指定的属性。

< em > update_attribute < / em >

该方法更新对象的单个属性,而不调用基于模型的验证。

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

< em > update_attributes < / em >

该方法更新单个对象的多个属性,并通过基于模型的验证。

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

希望这个答案能帮你理清什么时候用什么方法主动备案。

update_attributeupdate_attributes是相似的,但是 update_attribute 运行验证。

另外:

  • update_attribute用于更新具有属性的记录。

    Model.update_attribute(:column_name, column_value1)
    
  • update_attributes is used to update record with multiple attributes.

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

These two methods are really easy to confuse given their similar names and works. Therefore, update_attribute is being removed in favor of update_column.

Now, in Rails4 you can use Model.update_column(:column_name, column_value) at the place of Model.update_attribute(:column_name, column_value)

Click here to get more info about update_column.

为了回答你的问题,update_attribute跳过预保存“验证”,但它仍在运行任何其他回调,如after_save等。因此,如果你真的想“只是更新列,跳过任何AR cruft”,那么你需要使用(显然)

Model.update_all(...)参见https://stackoverflow.com/a/7243777/32453

< p >好答案。 注意,对于ruby 1.9及以上版本,你可以(而且我认为应该)对update_attributes使用新的哈希语法:

Model.update_attributes(column1: "data", column2: "data")

update_attribute只是简单地更新模型的一个属性,但我们可以在update_attributes方法中传递多个属性。

例子:

user = User.last


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

它通过了验证

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

如果验证失败,它不会更新。

最近我遇到了update_attribute vs. update_attributes和验证问题,如此相似的名称,如此不同的行为,如此令人困惑。

为了将哈希传递给update_attribute并绕过验证,你可以这样做:

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

您可能有兴趣访问这篇关于所有可能的方法来分配属性或更新记录(更新到Rails 4) update_attribute, update, update_column, update_columns etc. http://www.davidverhasselt.com/set-attributes-in-activerecord/的博客文章。例如,它在运行验证、触摸对象的updated_at或触发回调等方面有所不同。

作为OP问题的答案,update_attribute不通过传递回调。