Rails:update_attribute vs update_attributes

the*_*gah 250 ruby-on-rails callback update-attributes

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

这两个都将更新对象,而不必明确告知AR更新.

Rails API说:

for update_attribute

更新单个属性并保存记录,而无需通过正常的验证过程.这对现有记录上的布尔标志特别有用.混合验证模块时,Base中的常规update_attribute方法将替换为此默认值.

for update_attributes

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

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

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

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

Sal*_*lil 323

请参考update_attribute.点击show source后,您将获得以下代码

      # 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
Run Code Online (Sandbox Code Playgroud)

现在参考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
Run Code Online (Sandbox Code Playgroud)

两者之间的区别是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")
Run Code Online (Sandbox Code Playgroud)

要么

Object.update_attributes :field1 => "value", :field2 => "value2", :field3 => "value3"
Run Code Online (Sandbox Code Playgroud)

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

Object.update_attributes(params[:user])
Run Code Online (Sandbox Code Playgroud)

  • 你关于回调的陈述是不正确的,至少在`Rails 3`中.它在[来源评论](https://github.com/rails/rails/blob/v3.2.11/activerecord/lib/active_record/persistence.rb#L173)中非常明确地说"调用了回调". (7认同)
  • @Batkins仍然没有运行验证 - 这是最重要的部分:) (3认同)
  • 至少从 **Rails 5.1** 开始,上面的链接不再准确。这些方法已移至 ActiveRecord::Persistence。你可以在这里找到更新的信息:[更新属性](http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-update_attribute)和这里[update_attributes](http://api.rubyonrails .org/classes/ActiveRecord/Persistence.html#method-i-update_attributes) 注意:`update_attributes` 现在是`update` 的别名 (2认同)

Mat*_*att 75

提示: update_attribute正在通过Commit a7f4b0a1在Rails 4中弃用.它update_attribute有利于update_column.

  • 这不再是真的; 该方法已重新添加.请参阅https://github.com/rails/rails/pull/6738#issuecomment-39584005 (41认同)
  • `update_attribute`跳过验证,但尊重回调,`update_column`将​​跳过验证和回调并且不会更新`:updated_at`,`update`是正常的函数,它将同时遵循回调和验证 (17认同)
  • 他们会不会下定决心 reset_column,update_column也已弃用. (2认同)
  • `update_column` 没有被弃用,但 `update_columns(name: value)` 是受欢迎的。`reset_column` 已被删除。 (2认同)

小智 15

update_attribute

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

obj = Model.find_by_id(params[:id])
obj.update_attribute :language, “java”
Run Code Online (Sandbox Code Playgroud)

update_attributes方法

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

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

希望这个答案能清楚何时使用什么方法的主动记录.


Kib*_*gon 12

另外值得注意的是,与仅更新指定属性的质量分配方法相比update_attribute,attr_accessible要更新的所需属性不需要白名单来更新它.update_attributesattr_accessible


小智 7

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

例:

user = User.last

#update_attribute
user.update_attribute(:status, "active")
Run Code Online (Sandbox Code Playgroud)

它通过了验证

#update_attributes
user.update_attributes(first_name: 'update name', status: "active")
Run Code Online (Sandbox Code Playgroud)

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


Ziv*_*ili 6

很棒的答案.请注意,对于ruby 1.9及以上版本,您可以(我认为应该)使用update_attributes的新哈希语法:

Model.update_attributes(column1: "data", column2: "data")
Run Code Online (Sandbox Code Playgroud)


ada*_*sko 6

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

作为OP的问题的答案update_attribute不是通过回调.


uma*_*uma 5

update_attributeupdate_attributes很相似,但有一个很大的区别:update_attribute 运行验证。

还:

鉴于这两种方法的名称和工作原理相似,很容易混淆。因此,update_attribute正在被删除以支持update_column.

现在,在Rails4中,您可以Model.update_column(:column_name, column_value)在以下位置使用Model.update_attribute(:column_name, column_value)

单击此处获取有关 的更多信息update_column