【问题标题】:Is there a way to bypass mass assignment protection?有没有办法绕过批量分配保护?
【发布时间】:2011-08-05 07:34:03
【问题描述】:

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

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

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

问题在于,这样做涉及批量分配,对于我没有赋予 attr_writer 能力的属性,这是不允许的(我被告知这是有充分理由的!)。

有没有一种方法可以仅针对此操作绕过批量分配保护?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 mass-assignment


    【解决方案1】:

    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
    

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

    user = User.new({ :name => 'Josh', :is_admin => true }, :without_protection => true)
    

    【讨论】:

    • 这应该是答案,IMO!
    • 另外,似乎可以在对new 的初始调用中传递without_protection: true(即user = User.new({name: 'Josh', is_admin: true}, without_protection: true)
    • 直接传递到create 操作时也可以工作:User.create({name: 'Josh', is_admin: true}, without_protection: true)
    【解决方案2】:

    编辑: kizzx2's 答案是更好的解决方案。

    有点骇人听闻,但是...

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

    这会调用属性 = 为 guard_protected_attributes 参数传递 false,这将跳过任何批量分配检查。

    【讨论】:

    • 感谢工作。不过,我必须修正两个小错字,“self”后面的点和 self.name.downcase 的大括号。
    【解决方案3】:

    您也可以通过这种方式创建一个不进行批量分配的用户。

    User.create do |user|
      user.name = "Josh"
    end
    

    你可能想把它放到一个方法中。

    new_user(name)
      User.create do |user|
        user.name = name
      end
    end
    

    【讨论】:

      猜你喜欢
      • 2023-02-03
      • 2017-11-24
      • 1970-01-01
      • 2014-07-13
      • 2011-12-11
      • 1970-01-01
      • 2020-12-10
      • 2022-11-11
      • 1970-01-01
      相关资源
      最近更新 更多