I have a db column which is a serialized Hash:
class Foo < ActiveRecord::Base
serialize :bar
end
When I store a hash inside of bar that is a few levels deep, the deeper levels do not seem to properly deserialize when I need them. Objects one level deep get deserialzed just fine. However, objects 2 or more levels deep remain YAML classes.
I tried manually deserializing using YAML::load() but got an error saying the argument wasn’t an instance of IO.
Does anyone know why the complete Ruby object doesn’t deserialize?
EDIT: After further investigation, the problem seems to stem from the fact that I’m calling a virtual attribute from the serialized YAML.
class Foo < ActiveRecord::Base
serialize :bar
end
class Bar < ActiveRecord::Base
attr_accessor :enabled
end
@bars = @foo.bar[:bars]
@bars.each do |bar|
puts bar.enabled
end
yields:
NoMethodError: undefined method `enabled' for #<YAML::Object:0xb6f11844>
from (irb):12
from (irb):11:in `each'
from (irb):11
from :0
Does this mean deserialization isn’t “real”, ie, the YAML object acts similar to the original object, but it’s not an actual instance of that object?
There’s two things to keep in mind when serializing user-defined objects instead of “plain old Ruby” objects.
Generally serializing instances of an ActiveRecord::Base object is a bad idea as these have an extraordinary amount of baggage that will need to be encoded in addition to your attribute. It is best to build a class that is derived directly from Object, which is the default behavior, or from a simple base class of some sort.