YAML, delayed_job : Psych vs Syck. How to make pysch read attr_accessors for a ruby object

回眸只為那壹抹淺笑 提交于 2019-12-12 17:09:41

问题


I'm having problems using delayed_job (3.0.3) with ruby 1.9.3. Previously we were using ruby 1.8.7 which comes with yaml syck parser which read all the attributes that are set for a ruby object (including attr_accessors) but with the upgrade to 1.9.3 the yaml parser was switched to psych (which was re-written) and it doesn't take into account any attributes except those persisted in the database. How can we make psych to take the attr_accessors into account as well. I tried to switch to syck thru:

YAML::ENGINE.yamler = 'syck'

But still doesnt work.

Does anyone have a work around for this issue?


回答1:


The above hack doesn't work but all we need is to override the encode_with and init_with methods of ActiveRecord::Base to include attribute accessors. More precisely we need to set the coder hash with the att_accessors and that takes care of instance variable persistance.

Interesting read: https://gist.github.com/3011499




回答2:


The delayed_job deserializer does NOT call init_with on the loaded ActiveRecord object.

Here is a monkey patch for delayed_job that does call init_with on the resulting object: https://gist.github.com/4158475

For example with that monkey patch, if I had a model called Artwork with the extra attributes path and depth:

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


来源:https://stackoverflow.com/questions/13125777/yaml-delayed-job-psych-vs-syck-how-to-make-pysch-read-attr-accessors-for-a-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!