YAML,delayed_job:Psych vs Syck。如何让pysch读取attr_accessors以获取ruby对象

时间:2012-10-29 16:31:45

标签: yaml ruby-1.9.3 psych syck

我在使用带有ruby 1.9.3的delayed_job(3.0.3)时遇到了问题。以前我们使用的是ruby 1.8.7,它附带yaml syck解析器,它读取为ruby对象设置的所有属性(包括attr_accessors),但升级到1.9.3时,yaml解析器切换到psych(这是除了那些在数据库中持久存在的属性外,它没有考虑任何属性。我们怎样才能让心理也考虑到attr_accessors。我试图切换到syck thru:

YAML::ENGINE.yamler = 'syck'

但仍然无效。

有没有人可以解决这个问题?

2 个答案:

答案 0 :(得分:1)

上面的hack不起作用,但我们需要的是覆盖ActiveRecord :: Base的encode_with和init_with方法以包含属性访问器。更确切地说,我们需要使用att_accessors设置编码器哈希,并处理实例变量持久性。

有趣的阅读:https://gist.github.com/3011499

答案 1 :(得分:1)

delayed_job反序列化器不会在加载的ActiveRecord对象上调用init_with。

这是delayed_job的猴子补丁,它在结果对象上调用init_with:https://gist.github.com/4158475

例如,使用那个猴子补丁,如果我有一个名为Artwork的模型,其中包含额外的属性路径和深度:

class Artwork < ActiveRecord::Base
  def encode_with(coder)
    super

    coder['attributes']['path'] = self['path']
    coder['attributes']['depth'] = self['depth']
  end

  def init_with(coder)
    super

    if coder['attributes'].has_key? 'path'
      self['path'] = coder['attributes']['path']
    end

    if coder['attributes'].has_key? 'depth'
      self['depth'] = coder['attributes']['depth']
    end

    self
  end
end