Reputation: 64363
I have a serialized field called options(of type Hash) in my User model. The options field behaves like a Hash most of the time. When I convert the user object to XML, the 'options' field is serialized as a YAML type instead of Hash.
I am sending the result to a Flash client via REST. This behaviour is causing problems at the client side. Is there a way to address this?
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>
I am working around this issue by passing a block to to_xml.(similar to the solution suggested by molf)
u.to_xml(:except => [:options]) do |xml|
u.options.to_xml(:builder => xml, :skip_instruct => true, :root => 'options')
end
I wondering if there is a better way.
Upvotes: 2
Views: 1095
Reputation: 74985
Serialisation is done with YAML in the database. What they don't tell you is that it is also passed as YAML to the XML serializer. The last argument to serialize
indicates that the objects you assign to options
should be of type Hash
.
One solution to your problem is to override to_xml
with your own implementation. It's relatively easy to borrow the original xml builder object and pass it to to_xml
of your options
hash. Something like this should work:
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
Upvotes: 2