I understand how respond_to
works when it's called with something like this:
def index
@users = User.all
respond_to do |format|
format.html
format.json { render json: @users }
end
end
But I've seen some apps which pass respond_to
a list of symbols, outside of the controller methods, e.g.:
class UsersController < ApplicationController
respond_to :html, :json
def index
# blah blah bah
end
end
What does this do? I've been playing around with it in one of my controllers and I can't figure out what difference it makes.
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:
for an html response - if the request method is get, an exception is raised but for other requests such as post the response depends on whether the resource has any validation errors (i.e. assuming that an attempt has been made to save the resource, e.g. by a create action) -
If there are no errors, i.e. the resource was saved successfully, the response redirect's to the resource i.e. its show action.
If there are validation errors, the response renders a default action, which is :new for a post request or :edit for patch or put.
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
for a javascript request - if the template isn't found, an exception is raised.
for other requests - i.e. data formats such as xml, json, csv etc, if the resource passed to respond_with responds to to_, the method attempts to render the resource in the requested format directly, e.g. for an xml request, the response is equivalent to calling render xml: resource.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With