Custom-class serialization in ActiveRecord 3 - it's not what you think!

Short story:
Keep using composed_of to serialize attributes if you're looking to serialize attributes as JSON or another non-YAML format.

Long story:
With the introduction of Rails 3, we are now able to specify a custom class to ActiveRecord's serialize method.  At first, I was ready to concede and deprecate my composed_of attribute-serialization trick, but the behavior of serialize still uses YAML to encode your attributes.

The new custom-class serialization is not as pure as I originally thought.  Even thought it calls dump on the custom class, which can product JSON, the results are still stored as YAML.  Here's what I mean.

Say I create a settings class that supports ActiveRecord serialization:

class Settings < Hash
  def self.dump(settings)
    settings.to_json
  end

  def self.load(data)
    JSON.parse(data)
  end
end

And store it in my model:

class User < ActiveRecord::Base
  serialize :settings, Settings
end

Once I save the model, here's what goes into the database:

'--- !map:Settings {}\\n\\n'

So no, I've learned that the new serialize in Rails does not give you full control of attribute serialization and if you want to bypass YAML and keep full-control, keep using composed_of.

Posted on 22 Sep 2011