有没有办法绕过质量分配保护?

Dav*_*ite 24 ruby ruby-on-rails mass-assignment ruby-on-rails-3

我有一个Rails 3应用程序,JSON对对象进行编码,以便将它们存储在Redis键/值存储中.

当我检索对象时,我正在尝试解码JSON并从数据中实例化它们,如下所示:

def decode(json)
  self.new(ActiveSupport::JSON.decode(json)["#{self.name.downcase}"])
end
Run Code Online (Sandbox Code Playgroud)

问题是,这样做涉及质量分配,这是我不知道attr_writer能力的属性是不允许的(有充分理由我被告知!).

有没有办法可以绕过质量分配保护只是为了这个操作?

kiz*_*zx2 86

assign_attributeswithout_protection: true似乎不太侵扰:

user = User.new
user.assign_attributes({ :name => 'Josh', :is_admin => true }, :without_protection => true)
user.name       # => "Josh"
user.is_admin?  # => true
Run Code Online (Sandbox Code Playgroud)

@tovodeverett在评论中提到你也可以使用它new,就像在1行中一样

user = User.new({ :name => 'Josh', :is_admin => true }, :without_protection => true)
Run Code Online (Sandbox Code Playgroud)

  • 这应该是答案,IMO! (7认同)
  • 此外,似乎可以在初始调用`new`时传递`without_protection:true`(即`user = User.new({name:'Josh',is_admin:true},without_protection:true) (4认同)
  • 直接传递给`create`动作时也有效:`User.create({name:'Josh',is_admin:true},without_protection:true) (3认同)

Pau*_*der 7

编辑: kizzx2的答案是一个更好的解决方案.

有点黑客,但......

self.new do |n|
  n.send "attributes=", JSON.decode( json )["#{self.name.downcase}"], false
end
Run Code Online (Sandbox Code Playgroud)

这将为guard_protected_attributes参数调用attributes =传递false,这将跳过任何批量分配检查.