Rails:update_attribute vs update_attributes
Object.update_attribute(:only_one_field, "Some Value") Object.update_attributes(:field1 => "value", :field2 => "value2", :field3 => "value3")
这两个都将更新一个对象,而不必明确告诉AR更新。
Rails API说:
为update_attribute
更新单个属性并保存logging,而不需要经过正常的validation过程。 这对于现有logging上的布尔标志特别有用。 Base中的常规update_attribute方法在validation模块混入时replace为默认值。
为update_attributes
从传入的哈希中更新所有的属性并保存logging。 如果对象无效,则保存将失败,并返回false。
所以如果我不想validation对象,我应该使用update_attribute。 如果我在before_save上有这个更新,会怎样呢?
我的问题是,update_attribute也绕过之前保存或只是validation。
此外,什么是正确的语法传递给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
或者可以说save(true)
。
对不起,很长的描述,但我想说的是重要的。 save(perform_validation = true)
,如果perform_validation
为false,则绕过(跳过将是合适的词)与save
相关的所有validation 。
对于第二个问题
此外,什么是正确的语法传递给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
在Rails 4中通过Commit a7f4b0a1被弃用。 它将删除update_attribute
,以update_column
。
update_attribute
该方法更新对象的单个属性,而不用调用基于模型的validation。
obj = Model.find_by_id(params[:id]) obj.update_attribute :language, “java”
update_attributes方法
此方法更新单个对象的多个属性,并通过基于模型的validation。
attributes = {:name => “BalaChandar”, :age => 23} obj = Model.find_by_id(params[:id]) obj.update_attributes(attributes)
希望这个答案会清楚什么时候使用什么方法的主动logging。
另外值得注意的是,使用update_attribute
,需要更新的期望属性不需要用attr_accessible
进行白名单来更新,而不是使用只会更新attr_accessible
指定属性的批量分配方法update_attributes
。
很好的答案。 注意,对于ruby 1.9和以上版本,你可以(而且我认为应该)使用new_attributes的新哈希语法:
Model.update_attributes(column1: "data", column2: "data")
update_attribute
只更新模型的一个属性,但是我们可以在update_attributes
方法中传递多个属性。
例:
user = User.last #update_attribute user.update_attribute(:status, "active")
它通过validation
#update_attributes user.update_attributes(first_name: 'update name', status: "active")
如果validation失败,它不会更新。
您可能有兴趣访问此博客文章,了解分配属性或更新logging(更新到Rails 4)的所有可能方法: update_attribute, update, update_column, update_columns etc.
。http: update_attribute, update, update_column, update_columns etc.
in-activerecord / 。 例如,它在诸如运行validation,触摸对象的updated_at或触发callback等方面有所不同。
作为OP的问题的答案update_attribute
不通过callback。
为了回答你的问题,update_attribute跳过预保存“validation”,但它仍然运行像after_save
等任何其他callback。所以,如果你真的想“只更新列和跳过任何AR cruft”,那么你需要使用(显然)
Model.update_all(...)
请参阅https://stackoverflow.com/a/7243777/32453
最近我遇到了update_attribute
与update_attributes
和validation问题,所以类似的名字,如此不同的行为,如此混乱。
为了将hash传递给update_attribute
并绕过validation,你可以这样做:
object = Object.new object.attributes = { field1: 'value', field2: 'value2', field3: 'value3' } object.save!(validate: false)
update_attribute
和update_attributes
是相似的,但有一个很大的区别: update_attribute
不运行validation。
也:
-
update_attribute
用来更新单个属性的logging。Model.update_attribute(:column_name, column_value1)
-
update_attributes
用于更新具有多个属性的logging。Model.update_attributes(:column_name1 => column_value1, :column_name2 => column_value2, ...)
这两种方法由于类似的名字和作品而很容易混淆。 因此, update_attribute
正在被删除,以支持update_column
。
现在,在Rails4中,你可以在Model.update_attribute Model.update_column(:column_name, column_value)
的地方使用Model.update_attribute(:column_name, column_value)
点击这里获取更多关于update_column
信息。
我想你的问题是,如果在before_save中有一个update_attribute会导致无尽的循环(before_savecallback中的update_attribute调用,最初由update_attribute调用触发)
我很确定它确实绕过了before_savecallback,因为它实际上并没有保存logging。 您也可以保存logging,而不用通过使用触发validation
Model.save错误