YAML, delayed_job: Псих против Сика. Как заставить pysch читать attr_accessors для объекта ruby

У меня проблемы с использованием delayed_job (3.0.3) с ruby ​​1.9.3. Ранее мы использовали ruby ​​1.8.7, который поставляется с парсером yaml syck, который считывает все атрибуты, которые установлены для объекта ruby ​​(включая attr_accessors), но при обновлении до 1.9.3 парсер yaml был переключен на psy (который был повторно написано) и не учитывает никаких атрибутов, кроме тех, которые сохраняются в базе данных. Как мы можем сделать псих, чтобы принять во внимание attr_accessors. Я попытался переключиться на syck через:

YAML::ENGINE.yamler = 'syck'

Но все еще не работает.

У кого-нибудь есть решение этой проблемы?

2 ответа

Решение

Вышеупомянутый хак не работает, но все, что нам нужно, это переопределить методы encode_with и init_with ActiveRecord::Base, чтобы включить атрибуты доступа. Точнее, нам нужно установить хэш кодера с помощью att_accessors, и это позаботится о постоянстве переменных экземпляра.

Интересно почитать: https://gist.github.com/3011499

Десериализатор delayed_job НЕ вызывает init_with для загруженного объекта ActiveRecord.

Вот патч обезьяны для delayed_job, который вызывает init_with для результирующего объекта: https://gist.github.com/4158475

Например, с этим патчем обезьяны, если бы у меня была модель под названием Artwork с дополнительными атрибутами path и глубиной:

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
Другие вопросы по тегам