ActiveRecord serialize only saves data
We ran into an interesting gotcha on our project the other day. We use serialize on ActiveRecord to save ruby objects to the database. This is described in Jay Fields Thoughts: Rails: ActiveRecord Serialize method.
Serialize uses YAML.dump and YAML.load to serialize/deserialize objects to strings. These methods only deal with the data of an object, not the methods. The objects we serialized used metaprogramming to dynamically define methods. When they were loaded from the database, they no longer had the new methods.
Here is a contrived example. The Foo class creates a foo method in the initialize:
class Foo
def initialize
class << self
define_method :foo, lambda { 10 }
end
end
end
>> Foo.new.foo
=> 10
A dump of the Foo class has no knowledge of this foo method:
>> require 'yaml'
>> YAML.dump(Foo.new)
=> "--- !ruby/object:Foo {}\n\n"
Therefore, the loaded version of Foo will not have the foo method:
>>YAML.load(YAML.dump(Foo.new)).foo
NoMethodError: undefined method `foo' for #
from (irb):16
In our case, we changed our code to store only the data from the domain object in the database (in columns). We recreate the domain object from these columns when we need it.