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:i开发者_运维百科n `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.
- You need to have the user-defined classes loaded before the object can be properly de-serialized or the instances will be of a generic YAML::Object type. De-serializing does not auto-load classes.
- Some objects may not properly serialize without some customization, though this is generally not the case.
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.
This is a solution for nested YAML deserialization in case it helps: Ruby on Rails Class Serialize Problem by author etienne.
精彩评论