Проблема с сериализацией XML в сериализуемых атрибутах ActiveRecord - PullRequest
2 голосов
/ 06 февраля 2010

В моей модели User есть сериализованное поле с именем options (типа Hash). Поле параметров в большинстве случаев ведет себя как хэш. Когда я преобразую объект пользователя в XML, поле 'параметры' сериализуется как тип YAML, а не как Hash.

Я отправляю результат Flash-клиенту через REST. Такое поведение вызывает проблемы на стороне клиента. Есть ли способ решить эту проблему?

class User < ActiveRecord::Base
  serialize :options, Hash
end

u = User.first
u.options[:theme] =  "Foo"
u.save

p u.options # prints the Hash

u.to_xml    # options is serialized as a yaml type: 
            # <options type=\"yaml\">--- \n:theme: Foo\n</options>

EDIT:

Я работаю над этой проблемой, передавая блок to_xml. (Аналогично решению, предложенному molf)

u.to_xml(:except => [:options])  do |xml|
  u.options.to_xml(:builder => xml, :skip_instruct => true, :root => 'options')
end

Мне интересно, есть ли лучший способ.

1 Ответ

2 голосов
/ 06 февраля 2010

Сериализация выполняется с помощью YAML в базе данных. Они не говорят вам, что он также передается как YAML в сериализатор XML. Последний аргумент serialize указывает, что объекты, которые вы назначаете для options, должны иметь тип Hash.

Одним из решений вашей проблемы является переопределение to_xml с вашей собственной реализацией. Относительно легко заимствовать исходный объект xml builder и передавать его в to_xml вашего options хэша. Примерно так должно работать:

class User < ActiveRecord::Base
  serialize :options, Hash

  def to_xml(*args)
    super do |xml|
      # Hash#to_xml is unaware that the builder is in the middle of building
      # XML output, so we tell it to skip the <?xml...?> instruction. We also
      # tell it to use <options> as its root element name rather than <hash>.
      options.to_xml(:builder => xml, :skip_instruct => true, :root => "options")
    end
  end

  # ...
end
...