Using ActiveRecord’s serialize method you can save Ruby objects in a single field of your model. The serialization is done through YAML.
Today I tried to save a nested object structure with this method. These are the classes:
class PhotoStyle attr_accessor :image def initialize @image = StyleElement.new end end class StyleElement attr_accessor :selector, :style def initialize @selector = '*' @style = {} end end
The model which saves a PhotoStyle object:
class Photo < ActiveRecord::Base serialize :style, PhotoStyle end
This first approach didn’t quite work out. Saving the model worked fine, but when I loaded it only PhotoStyle got deserialized to the original type. The nested StyleElement didn’t:
p = Photo.last p.style => #<photostyle :0xb70a906c @image=#<YAML::Object:0xb72079a4 @ivars={"selector"=>"#theimage", "style"=>{"border"=>"0", "box-shadow"=>"1px 3px 15px #555"}}, @class="StyleElement">}, @class="PhotoStyle">> </photostyle>
Note the YAML object assigned to the @image instance variable.
I'm not sure if that's a bug in Rails3 or if that is by design. You can however "fix" it by running this code snippet when your application starts up:
YAML::Syck::Resolver.class_eval do def transfer_with_autoload(type, val) match = type.match(/object:(\w+(?:::\w+)*)/) match && match[1].constantize transfer_without_autoload(type, val) end alias_method_chain :transfer, :autoload end
Save it e.g. in yaml_autoloader.rb in the config/initializers folder of your app.
Now all types will autoload:
#<photostyle :0xb73dcb08 @image=#<StyleElement:0xb73dd058 @selector="#theimage", @style={"border"=>"0", "box-shadow"=>"1px 3px 15px #555"}>> </photostyle>
I found above code snippet here. Thanks!
Read more about ActiveRecord's serialize method here: Simple user preferences for your Rails app.
Update:
Still not sure if that's a bug, but I submitted a lighthouse ticket.
Update 2:
Apparently this is not a bug in Rails, but a problem in my code :-) Please see Aaron's comment in above ticket.

I'm a Software Developer, currently working at 