Rails的update_attributes没有保存?

有没有替代update_attributes不保存logging?

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

@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 

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

我相信你正在寻找的是assign_attributes

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

 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 

你可以使用assign_attributesattributes= (它们是一样的)

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

  • update_attributes = assign_attributes + save
  • attributes= = assign_attributes别名
  • update = update_attributes别名

资源:
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

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

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

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

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

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

如果guard_protected_attributes为true(默认值),那么敏感属性可以通过使用attr_protectedmacros来保护这种forms的质量分配。 或者,您也可以指定可以使用attr_accessiblemacros访问哪些属性。 那么不包括在内的所有属性都不能被批量分配。

 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 

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

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

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

请注意,这两种方法都不会执行validation或执行callback。 调用save时会发生callback和validation。

Rails 3

attributes=与Rails 3中的assign_attributes略有不同assign_attributes attributes=将检查传递给它的参数是否为散列值,如果不是,则立即返回; assign_attributes没有这样的散列检查。 查看attributes=的ActiveRecord属性分配API文档 。

下面的无效代码将通过简单地返回而无需设置属性而自动失败:

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

attributes=将默默地performance得好像分配成功了,但实际上它们不是。

assign_attributes尝试对封闭数组的散列键进行string化时,此无效代码将引发exception:

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

assign_attributes将引发stringify_keysNoMethodErrorexception,表明第一个参数不是散列。 这个exception本身对于实际的原因没有太多的信息,但是发生exception的事实是非常重要的。

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

这些例子可能看起来很有意思,并且在一定程度上,但是这种types的错误很容易发生在从API转换数据时,甚至只是使用一系列的数据转换和忘记Hash[]结果的最终.map 。 保持一些代码50行以上,3个function从你的属性分配中删除,你有一个失败的秘诀。

Rails 3的教训是: 总是使用assign_attributes而不是attributes=

Rails 4

在Rails 4中, attributes=只是assign_attributes一个别名。 查看attributes=的ActiveRecord属性分配API文档 。

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

validation

如果您在准备save前进行预分配,那么您也可能在保存之前对validation有兴趣。 你可以使用valid?invalid? 方法为此。 两者都返回布尔值。 valid? 如果未保存模型通过所有validation,则返回true,否则返回false。 invalid? 简直就是valid?的倒数valid?

valid? 可以这样使用:

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

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

Interesting Posts