达利:您正在尝试缓存无法序列化为memcached的Ruby对象 [英] Dalli: You are trying to cache a Ruby object which cannot be serialized to memcached

查看:112
本文介绍了达利:您正在尝试缓存无法序列化为memcached的Ruby对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试将内存中的对象保存到数据库,然后使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆