Aug 26 2007
Ruby on Rails Class Serialize Problem
I’ve been chasing my tail for the past day trying to track down a problem I was having in serializing a hash that contained two of my custom classes. I have two custom classes:
class Menu
…
endclass Permissions
…
end
I then have an ActiveRecord class that stores instances of these two classes in a hash which is then saved to my database.
class Role < ActiveRecord::Base
serialize :credentials
…
self.credentials[:permissions] = Permissions.new(self)
self.credentials[:menu] = Menu.new(self)
…
end
After saving the record to the database I could inspect the field and all the YAML code was present and accounted for, the problem was that when I went to retrieve the serialized field, instead of getting back a hash with my two custom classes (i.e. Menu and Permissions) I was getting both objects of class YAML::Object.
After pulling my hair out for some time, I traced into the Rails code and saw that YAML::Load(string) was being called to unserialize the data. I then went to the YAML site and read more about the library which I admit I have limited knowledge about. I figured out that for some reason YAML was not finding my custom class definitions which meant it used YAML::Object. So now it was a matter of finding out how to tell YAML about my classes.
After doing more searching on the net I came across these articles which gave me the information I needed:
http://yaml4r.sourceforge.net/doc/page/type_families.htm
http://dev.rubyonrails.org/ticket/7537
I was able to add the following code to my environment.rb which will ensure any ActiveRecord derived classes will be correctly serialized. I also added two require statements to environment.rb to make sure my custom (non ActiveRecord derived) classes where also correctly serialized.
require ‘permissions’
require ‘menu’…
YAML.add_domain_type("ActiveRecord,2007", "") do |type, val|
klass = type.split(’:').last.constantize
YAML.object_maker(klass, val)
endclass ActiveRecord::Base
def to_yaml_type
"!ActiveRecord,2007/#{self.class}"
end
endclass ActiveRecord::Base
def to_yaml_properties
[’@attributes’]
end
end
I restarted my server and everything worked !!!

