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 从传入的 Hash 中更新所有属性并保存记录。如果对象无效,则保存失败,返回false。
因此,如果我不想验证对象,我应该使用 #update_attribute
。如果我在 #before_save
上有此更新,它会溢出吗?
我的问题是 #update_attribute
是否也绕过了之前的保存或只是验证。
此外,将散列传递给 #update_attributes
的正确语法是什么……查看我在顶部的示例。
update_attribute
语句放在 before_save
回调中?我想不出一个很好的理由。
before_save
回调中设置的)。 Fe 代替 update_attribute(:discount, 0.1) if amount > 100
你可以做 discount = 0.1 if amount > 100
。 update_attribute
在对象上调用 save
,在这种情况下这是不必要的,因为该语句在 before_save
回调中并且无论如何都会被保存。我希望这是有道理的。
请参阅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
关联的所有 validations。
对于第二个问题
此外,将散列传递给 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])
提示: update_attribute
通过 Commit a7f4b0a1 在 Rails 4 中被弃用。它删除 update_attribute
以支持 update_column
。
update_attribute
跳过验证,但尊重回调,update_column
将跳过验证和回调并且不会更新 :updated_at
,update
是尊重回调和验证的普通函数
update_column
未被弃用,但 update_columns(name: value)
受到青睐。 reset_column
已被删除。
更新属性
此方法在不调用基于模型的验证的情况下更新对象的单个属性。
obj = Model.find_by_id(params[:id])
obj.update_attribute :language, “java”
更新属性
此方法更新单个对象的多个属性并通过基于模型的验证。
attributes = {:name => “BalaChandar”, :age => 23}
obj = Model.find_by_id(params[:id])
obj.update_attributes(attributes)
希望这个答案能明确何时使用什么方法进行活动记录。
另外值得注意的是,对于 update_attribute
,要更新的所需属性不需要与 attr_accessible
一起被列入白名单来更新它,而批量分配方法 update_attributes
只会更新 attr_accessible
指定的属性.
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")
如果验证失败,它不会更新。
您可能有兴趣访问这篇关于分配属性或更新记录的所有可能方法的博文(更新到 Rails 4)update_attribute, update, update_column, update_columns etc.
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")
update_attribute
和 update_attributes
相似,但有一个很大区别:update_attribute
不运行验证。
还:
update_attribute 用于更新具有单个属性的记录。 Model.update_attribute(:column_name, column_value1)
update_attributes 用于更新具有多个属性的记录。 Model.update_attributes(:column_name1 => column_value1, :column_name2 => column_value2, ...)
鉴于它们相似的名称和工作方式,这两种方法很容易混淆。因此,update_attribute
被删除以支持 update_column
。
现在,在 Rails4 中,您可以在 Model.update_attribute(:column_name, column_value)
的位置使用 Model.update_column(:column_name, column_value)
Click here 以获取有关 update_column
的更多信息。
要回答您的问题,update_attribute
会跳过预保存“验证”,但它仍会运行任何其他回调,例如 after_save
等。因此,如果您真的想要“只需更新列并跳过任何 AR 杂项" 那么你需要使用(显然)
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)
我认为您的问题是,如果在 before_save 中有 update_attribute 会导致无限循环(在 before_save 回调中调用 update_attribute,最初由 update_attribute 调用触发)
我很确定它确实绕过了 before_save 回调,因为它实际上并没有保存记录。您还可以使用以下方法保存记录而不触发验证
模型.save false
Rails 3
中是这样。它在 the comments in the source 中非常明确地说“调用了回调”。update_attributes
现在是update
的别名