Rails update_attributes没有保存?

本文翻译自:Rails update_attributes without save?

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' ,但是我想一次全部更新它们。


#1楼

参考:https://stackoom.com/question/SPHC/Rails-update-attributes没有保存


#2楼

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

#3楼

You can use assign_attributes or attributes= (they're the same) 您可以使用assign_attributesattributes= (它们相同)

Update methods cheat sheet (for Rails 6): 更新方法备忘单(适用于Rails 6):

  • update = assign_attributes + save update = assign_attributes + save
  • attributes= = alias of assign_attributes attributes= = assign_attributes别名
  • update_attributes = deprecated, alias of update 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/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/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


#4楼

For mass assignment of values to an ActiveRecord model without saving, use either the assign_attributes or attributes= methods. 要在不保存的情况下将值批量分配给ActiveRecord模型,请使用assign_attributesattributes=方法。 These methods are available in Rails 3 and newer. 这些方法在Rails 3和更高版本中可用。 However, there are minor differences and version-related gotchas to be aware of. 但是,需要注意一些细微的差异以及与版本相关的陷阱。

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 save is called. 调用save时将发生回调和验证。

Rails 3 导轨3

attributes= differs slightly from assign_attributes in Rails 3. attributes= will check that the argument passed to it is a Hash, and returns immediately if it is not; attributes=与Rails 3中的assign_attributes略有不同assign_attributes attributes=将检查传递给它的参数是否为哈希,如果不是,则立即返回;否则,返回false。 assign_attributes has no such Hash check. assign_attributes没有此类哈希检查。 See the ActiveRecord Attribute Assignment API documentation for 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_attributes tries to stringify the hash keys of the enclosing array: assign_attributes尝试对封闭数组的哈希键进行字符串化时,此无效代码将引发异常:

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

assign_attributes will raise a NoMethodError exception for stringify_keys , indicating that the first argument is not a Hash. assign_attributes将引发NoMethodError异常stringify_keys ,表明第一个参数是不是哈希。 The exception itself is not very informative about the actual cause, but the fact that an exception does occur is very important. 异常本身并不能很好地说明实际原因,但是异常确实发生的事实非常重要。

The only difference between these cases is the method used for mass assignment: attributes= silently succeeds, and assign_attributes raises 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 . 这些示例在某种程度上似乎是人为的,但是当从API转换数据,甚至只是使用一系列数据转换而忘记将最终.map的结果传递给Hash[]时,此类错误很容易发生。 。 Maintain some code 50 lines above and 3 functions removed from your attribute assignment, and you've got a recipe for failure. 保持上面的50行代码和从属性分配中删除的3个功能,您将获得失败的秘诀。

The lesson with Rails 3 is this: always use assign_attributes instead of attributes= . Rails 3的课程是: 始终使用assign_attributes而不是attributes=

Rails 4 滑轨4

In Rails 4, attributes= is simply an alias to assign_attributes . 在Rails 4中, attributes=只是assign_attributes的别名。 See the ActiveRecord Attribute Assignment API documentation for attributes= . 请参阅ActiveRecord属性分配API文档以获取attributes=

With Rails 4, either method may be used interchangeably. 对于Rails 4,这两种方法都可以互换使用。 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. 未能将哈希作为第一个参数传递将导致一个非常有用的异常: 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. 如果您在准备save前进行飞行检查,那么您可能也有兴趣在保存之前进行验证。 You can use the valid? 您可以使用valid? and invalid? invalid? methods for this. 方法。 Both return boolean values. 两者都返回布尔值。 valid? returns true if the unsaved model passes all validations or false if it does not. 如果未保存的模型通过所有验证,则返回true;否则,返回false。 invalid? is simply the inverse of valid? 就是valid?的反函数valid?

valid? can be used like this: 可以这样使用:

@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之前处理所有验证问题。


#5楼

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. 如果guard_protected_attributes为true(默认设置),则可以使用attr_protected宏保护敏感属性免受这种形式的批量分配。 Or you can alternatively specify which attributes can be accessed with the attr_accessible macro. 或者,您也可以指定可以使用attr_accessible宏访问哪些属性。 Then all the attributes not included in that won't be allowed to be mass-assigned. 这样一来,所有未包含在其中的属性都将无法进行大规模分配。

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值