Parent

Class Index [+]

Quicksearch

ActionController::Responder

Responder is responsible for exposing a resource to different mime requests, usually depending on the HTTP verb. The responder is triggered when respond_with is called. The simplest case to study is a GET request:

  class PeopleController < ApplicationController
    respond_to :html, :xml, :json

    def index
      @people = Person.find(:all)
      respond_with(@people)
    end
  end

When a request comes in, for example for an XML response, three steps happen:

  1) the responder searches for a template at people/index.xml;

  2) if the template is not available, it will invoke <code>#to_xml</code> on the given resource;

  3) if the responder does not <code>respond_to :to_xml</code>, call <code>#to_format</code> on it.

Builtin HTTP verb semantics

The default Rails responder holds semantics for each HTTP verb. Depending on the content type, verb and the resource status, it will behave differently.

Using Rails default responder, a POST request for creating an object could be written as:

  def create
    @user = User.new(params[:user])
    flash[:notice] = 'User was successfully created.' if @user.save
    respond_with(@user)
  end

Which is exactly the same as:

  def create
    @user = User.new(params[:user])

    respond_to do |format|
      if @user.save
        flash[:notice] = 'User was successfully created.'
        format.html { redirect_to(@user) }
        format.xml { render :xml => @user, :status => :created, :location => @user }
      else
        format.html { render :action => "new" }
        format.xml { render :xml => @user.errors, :status => :unprocessable_entity }
      end
    end
  end

The same happens for PUT and DELETE requests.

Nested resources

You can supply nested resources as you do in form_for and polymorphic_url. Consider the project has many tasks example. The create action for TasksController would be like:

  def create
    @project = Project.find(params[:project_id])
    @task = @project.comments.build(params[:task])
    flash[:notice] = 'Task was successfully created.' if @task.save
    respond_with(@project, @task)
  end

Giving an array of resources, you ensure that the responder will redirect to project_task_url instead of task_url.

Namespaced and singleton resources require a symbol to be given, as in polymorphic urls. If a project has one manager which has many tasks, it should be invoked as:

  respond_with(@project, :manager, @task)

Check polymorphic_url documentation for more examples.

Constants

ACTIONS_FOR_VERBS

Attributes

controller[R]
request[R]
format[R]
resource[R]
resources[R]
options[R]

Public Class Methods

call(*args) click to toggle source

Initializes a new responder an invoke the proper format. If the format is not defined, call to_format.

     # File lib/action_controller/metal/responder.rb, line 111
111:     def self.call(*args)
112:       new(*args).respond
113:     end
new(controller, resources, options={}) click to toggle source
    # File lib/action_controller/metal/responder.rb, line 90
90:     def initialize(controller, resources, options={})
91:       @controller = controller
92:       @request = @controller.request
93:       @format = @controller.formats.first
94:       @resource = resources.last
95:       @resources = resources
96:       @options = options
97:       @action = options.delete(:action)
98:       @default_response = options.delete(:default_response)
99:     end

Public Instance Methods

respond() click to toggle source

Main entry point for responder responsible to dispatch to the proper format.

     # File lib/action_controller/metal/responder.rb, line 117
117:     def respond
118:       method = :"to_#{format}"
119:       respond_to?(method) ? send(method) : to_format
120:     end
to_format() click to toggle source

All other formats follow the procedure below. First we try to render a template, if the template is not available, we verify if the resource responds to :to_format and display it.

     # File lib/action_controller/metal/responder.rb, line 135
135:     def to_format
136:       default_render
137:     rescue ActionView::MissingTemplate => e
138:       api_behavior(e)
139:     end
to_html() click to toggle source

HTML format does not render the resource, it always attempt to render a template.

     # File lib/action_controller/metal/responder.rb, line 125
125:     def to_html
126:       default_render
127:     rescue ActionView::MissingTemplate => e
128:       navigation_behavior(e)
129:     end

Protected Instance Methods

api_behavior(error) click to toggle source

This is the common behavior for “API” requests, like :xml and :json.

     # File lib/action_controller/metal/responder.rb, line 155
155:     def api_behavior(error)
156:       raise error unless resourceful?
157: 
158:       if get?
159:         display resource
160:       elsif has_errors?
161:         display resource.errors, :status => :unprocessable_entity
162:       elsif post?
163:         display resource, :status => :created, :location => api_location
164:       elsif has_empty_resource_definition?
165:         display empty_resource, :status => :ok
166:       else
167:         head :ok
168:       end
169:     end
api_location() click to toggle source
Alias for: resource_location
default_action() click to toggle source

By default, render the :edit action for HTML requests with failure, unless the verb is POST.

     # File lib/action_controller/metal/responder.rb, line 223
223:     def default_action
224:       @action ||= ACTIONS_FOR_VERBS[request.request_method_symbol]
225:     end
default_render() click to toggle source

If a given response block was given, use it, otherwise call render on controller.

     # File lib/action_controller/metal/responder.rb, line 189
189:     def default_render
190:       @default_response.call
191:     end
display(resource, given_options={}) click to toggle source

Display is just a shortcut to render a resource with the current format.

  display @user, :status => :ok

For XML requests it’s equivalent to:

  render :xml => @user, :status => :ok

Options sent by the user are also used:

  respond_with(@user, :status => :created)
  display(@user, :status => :ok)

Results in:

  render :xml => @user, :status => :created
     # File lib/action_controller/metal/responder.rb, line 210
210:     def display(resource, given_options={})
211:       controller.render given_options.merge!(options).merge!(format => resource)
212:     end
empty_json_resource() click to toggle source

Return a valid empty JSON resource

     # File lib/action_controller/metal/responder.rb, line 241
241:     def empty_json_resource
242:       "{}"
243:     end
empty_resource() click to toggle source

Delegate to proper empty resource method

     # File lib/action_controller/metal/responder.rb, line 235
235:     def empty_resource
236:       send("empty_#{format}_resource")
237:     end
has_empty_resource_definition?() click to toggle source

Check whether resource needs a specific definition of empty resource to be valid

     # File lib/action_controller/metal/responder.rb, line 229
229:     def has_empty_resource_definition?
230:       respond_to?("empty_#{format}_resource")
231:     end
has_errors?() click to toggle source

Check whether the resource has errors.

     # File lib/action_controller/metal/responder.rb, line 216
216:     def has_errors?
217:       resource.respond_to?(:errors) && !resource.errors.empty?
218:     end
resource_location() click to toggle source

Returns the resource location by retrieving it from the options or returning the resources array.

     # File lib/action_controller/metal/responder.rb, line 180
180:     def resource_location
181:       options[:location] || resources
182:     end
Also aliased as: navigation_location, api_location
resourceful?() click to toggle source

Checks whether the resource responds to the current format or not.

     # File lib/action_controller/metal/responder.rb, line 173
173:     def resourceful?
174:       resource.respond_to?(:"to_#{format}")
175:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.