Thursday, March 22, 2007

Rails: ActiveRecord Serialize method

On my current project we have a model with a few attributes that are instances. Generally, this is handled with a relationship (e.g. belongs_to). However, these attributes are not ActiveRecord::Base subclass instances. ActiveRecord handles this situation by providing the ActiveRecord::Base.serialize class method.

As a contrived example, imagine a UserAccount class that has a AuthorizationConfirmation instance as an attribute.
class CreateModels < ActiveRecord::Migration
def self.up
create_table :user_accounts do |t|
t.column :authorization_confirmation, :string
end
end

def self.down
drop_table :user_accounts
end
end

class UserAccount < ActiveRecord::Base
serialize :authorization_confirmation, AuthorizationConfirmation
end

class AuthorizationConfirmation
attr_accessor :fingerprint, :key
end
As you can see in the above example, the UserAccount class has the attribute authorization_confirmation. The value stored in authorization_confirmation is expected to be an instance of the AuthorizationConfirmation class.

A simple test proves the expected behavior.
require File.expand_path(File.dirname(__FILE__) + "/../test_helper")

class UserAccountTest < Test::Unit::TestCase
def test_authorization_confirmation_is_serialized_and_deserialized
account = UserAccount.new
account.authorization_confirmation = AuthorizationConfirmation.new
account.authorization_confirmation.fingerprint = "Xc1sseE"
account.authorization_confirmation.key = "gEteEQ"
account.save
retrieved = UserAccount.find account.id
assert_equal "Xc1sseE", retrieved.authorization_confirmation.fingerprint
assert_equal "gEteEQ", retrieved.authorization_confirmation.key
end
end
The test proves that the instance of AuthorizationConfirmation is saved and retrieved as expected.

A quick peek in the database shows the instance as yaml.
 id | authorization_confirmation                           
----+------+-------------------------------------------------------------------------------
6 | --- !ruby/object:AuthorizationConfirmation
fingerprint: Xc1sseE
key: gEteEQ
NOTE: At the time of this writing any attribute that is serialized cannot be nil. Ticket 7293 should resolve this problem.
Post a Comment