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_attributes或attributes= (它们是一样的)
更新方法备忘单(适用于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_attributes或attributes=方法。 这些方法在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_keys的NoMethodErrorexception,表明第一个参数不是散列。 这个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问题。