我正在向我的Rails应用添加缓存,我正在做的一件事是使用.new
方法(而不是.create
)实例化ActiveRecord模型,所以它不会尝试创建一个新行。
例如,如果我将其添加到我的模型中:
def from_json(json)
o = self.new
ActiveSupport::JSON.decode(json).each do |k, v|
# NOTE: I am doing this instead of sending all the params to .new
# because Rails won't let me bulk update protected attributes
o.send(k + '=', v)
end
o
end
然后从缓存中实例化一个对象:
o = Foo.from_json(redis.get(key))
在我尝试更改字段之前,一切似乎都运行良好:
o.bar = "spam and eggs"
o.save
我得到一个例外,说这是一个重复的条目。
如何告诉ActiveRecord这个实际引用数据库中已存在的行,以便它更新该行而不是抛出和异常?
答案 0 :(得分:3)
我需要的答案可以在lib/active_record/base.rb
中找到。我需要将new_record
设置为false
来初始化对象,执行此操作的方法是分配对象,然后使用init_with
对其进行初始化。请注意,您需要使用定义的编码器正确序列化特殊serialized_attributes
。
请注意,我使用的是Rail 3.1。
def serialize_for_cache
h = self.attributes.clone
self.class.serialized_attributes.each do |key, coder|
h[key] = coder.dump(h[key])
end
ActiveSupport::JSON.encode(h)
end
def deserialize_from_cache(json)
self.allocate.init_with('attributes' => ActiveSupport::JSON.decode(json))
end