24

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

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

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

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

有没有办法仅针对此操作绕过批量分配保护?

4

3 回答 3

86

assign_attributeswithwithout_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)
于 2012-08-21T02:47:46.440 回答
7

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

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

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

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

于 2011-04-14T07:22:09.707 回答
4

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

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

您可能希望将其放入方法中。

new_user(name)
  User.create do |user|
    user.name = name
  end
end
于 2012-11-08T20:28:28.383 回答