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
的NoMethodError
exception,表明第一个参数不是散列。 这个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问题。