达利:您正在尝试缓存无法序列化为memcached的Ruby对象 [英] Dalli: You are trying to cache a Ruby object which cannot be serialized to memcached
问题描述
当我尝试将内存中的对象保存到数据库,然后使用Dalli缓存该对象时,我的行为变得怪异.
I'm getting weird behavior when I try to save an object in memory to the database and then cache that object with 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隐式保存到数据库中.
Notice that the objects (in the second case just the TrackedPoint
), is saved to the database implicitly by the call to create.
我还发现,重新加载i
允许我将对象写入高速缓存.如此有效:
I've also found that reloading i
allows me to write the object to the cache. So this works:
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
但是,如果我做了一些奇怪的欺骗,我可以使失败的示例起作用:
However, if I do some weird duping, I can get the failing example to work:
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
)保存到数据库之前对其进行缓存,如下所示:
In my failing example, I can cache the infraction (i
) before I save it to the database, like this:
i = Infraction.new
i.tracked_points << TrackedPoint.new(location_id: 1)
Rails.cache.write "what", i
按照戴夫(Dave)的想法,我尝试将build
替换为build
而不是<<
,并在Infraction
中添加了accepts_nested_attributes_for :tracked_points
,但没有一个起作用.
Per Dave's idea, I tried build
instead of <<
for the TrackedPoint
as well as adding a accepts_nested_attributes_for :tracked_points
to Infraction
, but neither of those worked.
我在日志中遇到编组/序列化器错误:
I am getting the marshalling/serializer error in the log:
You are trying to cache a Ruby object which cannot be serialized to memcached.
我正在运行Rails 3.2.13和Dalli 2.7.0
I am running Rails 3.2.13 and Dalli 2.7.0
编辑
另请参见:通过以下方式缓存具有has_many的ActiveRecord对象:
推荐答案
原来是squeel的问题.
Turns out it was a problem with squeel.
有一个称为AliasTracker的东西没有正确编组.似乎可以解决此问题的猴子补丁是:
There is something called an AliasTracker that is not being Marshalled correctly. A monkey patch that appears to fix this issue is:
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
More discussion and answer from here: https://github.com/activerecord-hackery/squeel/issues/232
这篇关于达利:您正在尝试缓存无法序列化为memcached的Ruby对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!