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.

Paul Gross

Paul Gross

I'm a lead software developer in Seattle working for Braintree Payments.

Read More