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

这两种方法都可以更新对象,而不必显式地告诉ActiveRecord更新。

Rails API说:

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

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

所以如果我不想验证对象,我应该使用#update_attribute。如果我在#before_save上有这个更新,它会stackoverflow吗?

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

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


当前回答

请参考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(true)。

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

第二个问题

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

你的例子是正确的。

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

or

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

或者如果你在哈希中获得所有字段数据和名称,在这里使用params[:user]

Object.update_attributes(params[:user])

其他回答

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

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

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

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

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

请参考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(true)。

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

第二个问题

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

你的例子是正确的。

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

or

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

或者如果你在哈希中获得所有字段数据和名称,在这里使用params[:user]

Object.update_attributes(params[:user])

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

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

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

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