Custom ActiveRecord Attribute Serialization
Rails 3.1
As you might know already, ActiveRecord lets you store serialized objects by using serialize in your model:
class User < ActiveRecord::Base
serialize :interests
end
These serializeable attributes can then be set as any Ruby type such as an array:
user = User.create!(:interests => ['dinosaurs', 'lasers'])
user.reload.interests # => ["dinosaurs", "lasers"]
Under the hood, this array is automatically converted to YAML. You won’t notice this unless you check what’s being inserted into your database:
INSERT INTO "users" ("updated_at", "interests", "created_at") VALUES ('2011-03-05 13:14:05.054192', '---
- dinosaurs
- lasers
', '2011-03-05 13:14:05.054192')
Using arbitrary objects
Aaron Patterson recently did some work for Rails 3.1 which allows you to use arbitrary objects to serialize your attributes, all they need to do is respond to load and dump. This allows you to specify a custom encoding for your models serialize fields. For example, here is what a Base64 encoding might look like:
class User < ActiveRecord::Base
class Base64
def load(text)
return unless text
text.unpack('m').first
end
def dump(text)
[text].pack 'm'
end
end
serialize :bank_account_number, Base64.new
end
Just like the default YAML serialization, ActiveRecord won’t bother you with any serialized data, unless you check the SQL query:
user = User.create!(:bank_account_number => "0000001 00000011 0000001 00000011")
user.reload
user.bank_account_number # => "0000001 00000011 0000001 00000011"
INSERT INTO "users" ("updated_at", "bank_account_number", "created_at") VALUES ('2011-03-05 17:12:01.459862', 'MDAwMDAwMSAwMDAwMDAxMSAwMDAwMDAxIDAwMDAwMDEx\n', '2011-03-05 17:12:01.459862')
Just remember, YAML serialization is still used by default, but creating your own serialization object is as simple as load and dump.