| Module | ActionController::RespondWith |
| In: |
lib/action_controller/respond_with.rb
|
For a given controller action, respond_with generates an appropriate response based on the mime-type requested by the client.
If the method is called with just a resource, as in this example -
class PeopleController < ApplicationController
respond_to :html, :xml, :json
def index
@people = Person.all
respond_with @people
end
end
then the mime-type of the response is typically selected based on the request‘s Accept header and the set of available formats declared by previous calls to the controller‘s class method respond_to. Alternatively the mime-type can be selected by explicitly setting request.format in the controller.
If an acceptable format is not identified, the application returns a ‘406 - not acceptable’ status. Otherwise, the default response is to render a template named after the current action and the selected format, e.g. index.html.erb. If no template is available, the behavior depends on the selected format:
Thus an example like this -
respond_to :html, :xml
def create
@user = User.new(params[:user])
flash[:notice] = 'User was successfully created.' if @user.save
respond_with(@user)
end
is equivalent, in the absence of create.html.erb, to -
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 }
else
format.html { render action: "new" }
format.xml { render xml: @user }
end
end
end
As outlined above, the resources argument passed to respond_with can play two roles. It can be used to generate the redirect url for successful html requests (e.g. for create actions when no template exists), while for formats other than html and JavaScript it is the object that gets rendered, by being converted directly to the required format (again assuming no template exists).
For redirecting successful html requests, respond_with also supports the use of nested resources, which are supplied in the same way as in form_for and polymorphic_url. For example -
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
This would cause respond_with to redirect to project_task_url instead of task_url. For request formats other than html or JavaScript, if multiple resources are passed in this way, it is the last one specified that is rendered.
Like respond_to, respond_with may also be called with a block that can be used to overwrite any of the default responses, e.g. -
def create
@user = User.new(params[:user])
flash[:notice] = "User was successfully created." if @user.save
respond_with(@user) do |format|
format.html { render }
end
end
The argument passed to the block is an ActionController::MimeResponds::Collector object which stores the responses for the formats defined within the block. Note that formats with responses defined explicitly in this way do not have to first be declared using the class method respond_to.
Also, a hash passed to respond_with immediately after the specified resource(s) is interpreted as a set of options relevant to all formats. Any option accepted by render can be used, e.g.
respond_with @people, status: 200
However, note that these options are ignored after an unsuccessful attempt to save a resource, e.g. when automatically rendering :new after a post request.
Three additional options are relevant specifically to respond_with -
respond_with(resource, render: { template: ‘path/to/template’, status: 422 })