Ruby-on-rails Rails update_attributes 没有保存?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6770350/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 01:38:20  来源:igfitidea点击:

Rails update_attributes without save?

ruby-on-railsrubyruby-on-rails-3ruby-on-rails-4rails-activerecord

提问by tybro0103

Is there an alternative to update_attributes that does not save the record?

是否有不保存记录的 update_attributes 的替代方法?

So I could do something like:

所以我可以做这样的事情:

@car = Car.new(:make => 'GMC')
#other processing
@car.update_attributes(:model => 'Sierra', :year => "2012", :looks => "Super Sexy, wanna make love to it")
#other processing
@car.save

BTW, I know I can @car.model = 'Sierra', but I want to update them all on one line.

顺便说一句,我知道我可以@car.model = 'Sierra',但我想在一行上更新它们。

回答by Ajedi32

I believe what you are looking for is assign_attributes.

我相信你正在寻找的是assign_attributes.

It's basically the same as update_attributes but it doesn't save the record:

它与 update_attributes 基本相同,但不保存记录:

class User < ActiveRecord::Base
  attr_accessible :name
  attr_accessible :name, :is_admin, :as => :admin
end

user = User.new
user.assign_attributes({ :name => 'Josh', :is_admin => true }) # Raises an ActiveModel::MassAssignmentSecurity::Error
user.assign_attributes({ :name => 'Bob'})
user.name        # => "Bob"
user.is_admin?   # => false
user.new_record? # => true

回答by Yarin

You can use assign_attributesor attributes=(they're the same)

您可以使用assign_attributesattributes=(它们是相同的)

Update methods cheat sheet (for Rails 6):

更新方法备忘单(适用于 Rails 6):

  • update= assign_attributes+ save
  • attributes== alias of assign_attributes
  • update_attributes= deprecated, alias of update
  • update= assign_attributes+save
  • attributes== 别名 assign_attributes
  • update_attributes= 已弃用,别名 update

Source:
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/persistence.rb
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_assignment.rb

来源:
https : //github.com/rails/rails/blob/master/activerecord/lib/active_record/persistence.rb
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_assignment .rb

Another cheat sheet:
http://www.davidverhasselt.com/set-attributes-in-activerecord/#cheat-sheet

另一个备忘单:http :
//www.davidverhasselt.com/set-attributes-in-activerecord/#cheat-sheet

回答by bruno077

You can use the 'attributes' method:

您可以使用“属性”方法:

@car.attributes = {:model => 'Sierra', :years => '1990', :looks => 'Sexy'}

Source: http://api.rubyonrails.org/classes/ActiveRecord/Base.html

来源:http: //api.rubyonrails.org/classes/ActiveRecord/Base.html

attributes=(new_attributes, guard_protected_attributes = true)Allows you to set all the attributes at once by passing in a hash with keys matching the attribute names (which again matches the column names).

attributes=(new_attributes,guard_protected_attributes = true)允许您通过传入具有与属性名称匹配的键(再次与列名称匹配)的哈希值来一次设置所有属性。

If guard_protected_attributes is true (the default), then sensitive attributes can be protected from this form of mass-assignment by using the attr_protected macro. Or you can alternatively specify which attributes can be accessed with the attr_accessible macro. Then all the attributes not included in that won't be allowed to be mass-assigned.

如果guard_protected_attributes 为true(默认值),则可以使用attr_protected 宏来保护敏感属性免受这种形式的批量赋值。或者,您也可以指定可以使用 attr_accessible 宏访问哪些属性。那么所有未包含在其中的属性将不允许被批量分配。

class User < ActiveRecord::Base
  attr_protected :is_admin
end

user = User.new
user.attributes = { :username => 'Phusion', :is_admin => true }
user.username   # => "Phusion"
user.is_admin?  # => false

user.send(:attributes=, { :username => 'Phusion', :is_admin => true }, false)
user.is_admin?  # => true

回答by Michael Gaskill

For mass assignment of values to an ActiveRecord model without saving, use either the assign_attributesor attributes=methods. These methods are available in Rails 3 and newer. However, there are minor differences and version-related gotchas to be aware of.

要在不保存的情况下将值批量分配给 ActiveRecord 模型,请使用assign_attributesattributes=方法。这些方法在 Rails 3 和更新版本中可用。但是,需要注意一些细微的差异和与版本相关的问题。

Both methods follow this usage:

两种方法都遵循这种用法:

@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }

@user.attributes = { model: "Sierra", year: "2012", looks: "Sexy" }

Note that neither method will perform validations or execute callbacks; callbacks and validation will happen when saveis called.

请注意,这两种方法都不会执行验证或执行回调;回调和验证将在save调用时发生。

Rails 3

导轨 3

attributes=differs slightly from assign_attributesin Rails 3. attributes=will check that the argument passed to it is a Hash, and returns immediately if it is not; assign_attributeshas no such Hash check. See the ActiveRecord Attribute Assignment API documentation for attributes=.

attributes=assign_attributesRails 3略有不同。 attributes=将检查传递给它的参数是否为 Hash,如果不是则立即返回;assign_attributes没有这样的哈希检查。请参阅ActiveRecord 属性分配 API 文档attributes=

The following invalid code will silently fail by simply returning without setting the attributes:

以下无效代码将通过简单地返回而不设置属性而静默失败:

@user.attributes = [ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ]

attributes=will silently behave as though the assignments were made successfully, when really, they were not.

attributes=会默默地表现得好像分配成功了,但实际上并非如此。

This invalid code will raise an exception when assign_attributestries to stringify the hash keys of the enclosing array:

assign_attributes尝试对封闭数组的哈希键进行字符串化时,此无效代码将引发异常:

@user.assign_attributes([ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ])

assign_attributeswill raise a NoMethodErrorexception for stringify_keys, indicating that the first argument is not a Hash. The exception itself is not very informative about the actual cause, but the fact that an exception does occur is veryimportant.

assign_attributes将为 引发NoMethodError异常stringify_keys,表明第一个参数不是哈希。异常本身并不能提供有关实际原因的信息,但异常确实发生这一事实非常重要。

The only difference between these cases is the method used for mass assignment: attributes=silently succeeds, and assign_attributesraises an exception to inform that an error has occurred.

这些情况之间的唯一区别是用于批量分配的方法:attributes=静默成功,并assign_attributes引发异常以通知发生了错误。

These examples may seem contrived, and they are to a degree, but this type of error can easily occur when converting data from an API, or even just using a series of data transformation and forgetting to Hash[]the results of the final .map. Maintain some code 50 lines above and 3 functions removed from your attribute assignment, and you've got a recipe for failure.

这些例子可能看起来很人为,在一定程度上也是如此,但是当从 API 转换数据时,甚至只是使用一系列数据转换而忘记Hash[]最终.map. 保留上面 50 行的一些代码,并从您的属性分配中删除 3 个函数,这样您就有了失败的秘诀。

The lesson with Rails 3 is this: alwaysuse assign_attributesinstead of attributes=.

Rails 3 的教训是:始终使用assign_attributes而不是attributes=.

Rails 4

导轨 4

In Rails 4, attributes=is simply an alias to assign_attributes. See the ActiveRecord Attribute Assignment API documentation for attributes=.

在 Rails 4 中,attributes=只是assign_attributes. 请参阅ActiveRecord 属性分配 API 文档attributes=

With Rails 4, either method may be used interchangeably. Failure to pass a Hash as the first argument will result in a very helpful exception: ArgumentError: When assigning attributes, you must pass a hash as an argument.

在 Rails 4 中,任何一种方法都可以互换使用。未能将 Hash 作为第一个参数传递将导致一个非常有用的异常:ArgumentError: When assigning attributes, you must pass a hash as an argument.

Validations

验证

If you're pre-flighting assignments in preparation to a save, you might be interested in validating before save, as well. You can use the valid?and invalid?methods for this. Both return boolean values. valid?returns true if the unsaved model passes all validations or false if it does not. invalid?is simply the inverse of valid?

如果您正在为 a 准备飞行前分配save,您可能也有兴趣在保存之前进行验证。您可以为此使用valid?invalid?方法。两者都返回布尔值。 valid?如果未保存的模型通过所有验证,则返回 true,否则返回 false。 invalid?只是相反valid?

valid?can be used like this:

valid?可以这样使用:

@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }.valid?

This will give you the ability to handle any validations issues in advance of calling save.

这将使您能够在调用之前处理任何验证问题save