我理解respond_to
在用这样的东西调用时是如何工作的:
def index
@users = User.all
respond_to do |format|
format.html
format.json { render json: @users }
end
end
但我看到一些应用程序在控制器方法之外传递respond_to
符号列表,例如:
class UsersController < ApplicationController
respond_to :html, :json
def index
# blah blah bah
end
end
这是做什么的?我一直在我的一个控制器中玩它,我无法弄清楚它有什么不同。
答案 0 :(得分:2)
对于给定的控制器操作,#response_with根据客户端请求的mime类型生成适当的响应。
如果仅使用资源调用该方法,如本示例所示 -
class PeopleController < ApplicationController
respond_to :html, :xml, :json
def index
@people = Person.all
respond_with @people
end
end
然后通常根据请求的Accept标头和先前调用控制器的类方法respond_to声明的可用格式集来选择响应的mime类型。或者,可以通过在控制器中显式设置request.format来选择mime-type。
如果未识别出可接受的格式,则应用程序将返回“406 - 不可接受”状态。否则,默认响应是呈现以当前操作和所选格式命名的模板,例如, index.html.erb。如果没有可用的模板,则行为取决于所选格式:
对于html响应 - 如果请求方法是get,则引发异常但是对于其他请求(例如发布响应)取决于资源是否有任何验证错误(即假设已尝试保存资源) ,例如通过创建动作) -
如果没有错误,即资源已成功保存,则响应重定向到资源,即显示操作。
如果存在验证错误,则响应将呈现默认操作,即:对于发布请求为new,或者为patch或put进行编辑。
这样的例子 -
respond_to :html, :xml
def create
@user = User.new(params[:user])
flash[:notice] = 'User was successfully created.' if @user.save
respond_with(@user)
end
在没有create.html.erb的情况下,等同于 -
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
对于javascript请求 - 如果找不到模板,则会引发异常。
对于其他请求 - 即数据格式,例如xml,json,csv等,如果传递给respond_with的资源响应to_,则该方法尝试直接以所请求的格式呈现资源,例如,对于xml请求,响应等同于调用render xml:resource。