Last Updated: February 25, 2016
·
1.233K
· craigmcnamara

Dynamically Switch Rails Responders

Need to be able to support totally different response behaviors dynamically?

Responder objects respond to #call, so do procs and lambdas.

Confusing? Let's read some abridged rails code.

def respond_with(*resources, &block)
  # respond_with stuff
  (options.delete(:responder) || self.class.responder).call(self, resources, options)
end

The last line of code in #respond_with looks for our responder and calls #call.

In our overridden method we return a lambda with receives the #call message and the arguments.

class SpecialResponderController < ActionController::Base
  protected
  def self.responder
    lambda do |controller, resources, options|
      if controller.is_special?
        SpecialResponder.call(controller, resources, options)
      else
        super.call(controller, resources, options)
      end
    end
  end
end

Since one of those arguments is the controller from our request we can use public instance methods of the controller to inform our responder behavior.

Hope it's helpful.