ActiveRecord可序列化属性中的XML序列化问题

时间:2010-02-05 21:46:07

标签: ruby-on-rails xml-serialization

我的User模型中有一个名为options(类型为Hash)的序列化字段。选项字段在大多数情况下表现得像哈希。当我将用户对象转换为XML时,'options'字段被序列化为YAML类型而不是Hash。

我通过REST将结果发送到Flash客户端。此行为导致客户端出现问题。有没有办法解决这个问题?

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>

编辑:

我正在通过将一个块传递给to_xml来解决这个问题。(类似于molf建议的解决方案)

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

我想知道是否有更好的方法。

1 个答案:

答案 0 :(得分:2)

使用数据库中的YAML完成序列化。他们没有告诉你的是它也作为YAML传递给XML序列化器。 serialize的最后一个参数表示您分配options的对象应为Hash类型。

您的问题的一个解决方案是使用您自己的实现覆盖to_xml。借用原始xml构建器对象并将其传递给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