Philip Cunningham music, code and stuff.

Decorating Active Record Scopes 20 February 2013

I recently ran into a problem in work where I wanted serialize the same Active Record model to JSON differently depending on context.

The solution I ended up going with was to wrap objects inside an Active Record scope in another object and proxy unknown messages to the internal object.

The example here is somewhat trivial but having these little objects helped add clarity to our JSON API.

class JSONDecorator

  attr_reader :instance

  def self.decorate(instances)
    instances.map {|instance| new(instance) }
  end

  def as_json(opts={})
    raise "define as_json method on subclass"
  end

  def initialize(instance)
    @instance = instance
  end

  def method_missing(method, *args, &block)
    instance.send(method, *args, &block)
  end

end
class ComedianAvailability < JSONDecorator

  def as_json(opts={})
    json = Hash.new
    json["id"]        = id
    json["name"]      = title
    json["rating"]    = url
    json["available"] = available
    json
  end

  def available
    active ? "yes" : "no"
  end

end
json_response = ComedianAvailability.decorate(Comedian.scoped).to_json