当我尝试将内存中的对象保存到数据库然后使用Dalli缓存该对象时,我得到了奇怪的行为。
class Infraction << ActiveRecord::Base
has_many :infraction_locations
has_many :tracked_points, through: :infraction_locations
end
class TrackedPoint << ActiveRecord::Base
has_many :infraction_locations
has_many :infractions, through: :infraction_locations
end
class InfractionLocation << ActiveRecord::Base
belongs_to :infraction
belongs_to :tracked_point
belongs_to :rule
end
这有效:
i = Infraction.create
i.tracked_points << TrackedPoint.create(location_id: 1)
i.save
Rails.cache.write "my_key", i
这也有效:
i = Infraction.new
i.tracked_points << TrackedPoint.create(location_id: 1)
i.save
Rails.cache.write "my_key", i
请注意,对象(在第二种情况下只是TrackedPoint
)通过调用create隐式地保存到数据库中。
我还发现重新加载i
允许我将对象写入缓存。所以这有效:
i = Infraction.new
i.tracked_points << TrackedPoint.new(location_id: 1)
i.save
i.reload
Rails.cache.write "my_key", i
这失败了:
i = Infraction.new
i.tracked_points << TrackedPoint.new(location_id: 1)
i.save
Rails.cache.write "my_key", i
但是,如果我做了一些奇怪的重复,我可以让失败的例子起作用:
i = Infraction.new
i.tracked_points << TrackedPoint.new(location_id: 1)
i.save
copy = i.dup
copy.tracked_points = i.tracked_points.to_a
Rails.cache.write "my_key", copy
在我失败的示例中,我可以在将其保存到数据库之前缓存违规行为(i
),如下所示:
i = Infraction.new
i.tracked_points << TrackedPoint.new(location_id: 1)
Rails.cache.write "what", i
Per Dave的想法,我为build
尝试了<<
而不是TrackedPoint
,并向accepts_nested_attributes_for :tracked_points
添加了Infraction
,但这些都没有
我在日志中收到编组/序列化程序错误:
You are trying to cache a Ruby object which cannot be serialized to memcached.
我正在运行Rails 3.2.13和Dalli 2.7.0
修改
答案 0 :(得分:0)
我最好的猜测,只需查看代码差异即可。
在前两个示例中,您使用TrackedPoint.create创建关联对象,该对象会立即将其保留在数据库中。因此,通过“&lt;&lt;”分配关联因为该对象有一个id。
在第三个中,使用TrackedPoint.new,然后分配对象。这将利用嵌套创建。所以你需要在模型中使用“accepts_nested_attributes_for”。 IIRC的正确方法是使用“build”来正确实例化新对象的关联。我的猜测是你看到一些奇怪的情况,当你在rails创建TrackedPoint对象时将其复制,因此它不再是嵌套属性的情况,它只是将现有对象直接分配给关联。
答案 1 :(得分:0)
原来这是一个吱吱声问题。
有一种称为AliasTracker的东西没有被正确编组。似乎解决了这个问题的猴子补丁是:
module ActiveRecord
module Associations
class AliasTracker
def marshal_dump(*)
nil
end
def marshal_load(*)
nil
end
end
end
end
更多讨论和答案来自:https://github.com/activerecord-hackery/squeel/issues/232