Rails 3.1 has a serialize
function that can take a custom column coder. A custom coder needs to have dump
and load
methods set, or else it will be recognized as a required type for the built-in YAML coder called YAMLColumn.
While the JSON class has the two required methods, it doesn’t allow specifying a default. So I created a custom coder. I don’t know where the best file and module locations to put the class in are, so I won’t include them here. This is the class, though:
class JSONColumn def initialize(default={}) @default = default end # this might be the database default and we should plan for empty strings or nils def load(s) s.present? ? JSON.load(s) : @default.clone end # this should only be nil or an object that serializes to JSON (like a hash or array) def dump(o) JSON.dump(o || @default) end end
Since load
and dump
are instance methods, an instance of JSONColumn needs to be passed rather than the class. Here’s an example that works for me inside of the rails console:
class Person < ActiveRecord::Base validate :name, :pets, :presence => true serialize :pets, JSONColumn.new([]) end
Update: Added .clone
to the load method. HT @miyagawa.