ActiveRecord Model Serialisation

I’ve been working on a JSON API for mobile clients recently, and in doing so I’ve realised how much you need to repeat serialisation options throughout Rails applications despite options generally being model specific.

This little patch solves that problem by allowing you to decorate your Rails models with model-wide serialisation options, like so:

ActiveRecord model with class-level serialisation options defined
1
2
3
4
class Article < ActiveRecord::Base
  has_many :comments
  serialization_options :include => :comments
end

This means that whenever you call to_json or to_xml on an instance of Article, you’ll get the comment association thrown in for you. You’ll find you can clean up your Controllers and remove explicit calling of to_json, which previously would have looked like this:

Defining serialisation options every time to_json is called
1
2
3
respond_to do |format|
  format.json :json => @article.to_json :include => :comments
end

But can now be change to this:

No longer any need to specify the options
1
2
3
respond_to do |format|
  format.json :json => @article
end

While it’s very simple, some people might find it useful. If you do, chuck this in your /lib directory and require it in RAILS_ROOT/config/environment.rb.

Allow class-level definition of serialisation options
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
module SerializationOptions
  def serialization_options(options = {})
    class_inheritable_accessor :serialization_options
    self.serialization_options = options.dup
  end
end

ActiveRecord::Base.send(:extend, SerializationOptions)

class ActiveRecord::Serialization::Serializer
  alias_method :old_initialize, :initialize
  def initialize(record, options = {})
    if record.respond_to? :serialization_options
      options = record.serialization_options.merge(options)
    end
    old_initialize(record, options)
  end
end