5

我理解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

这是做什么的?我一直在我的一个控制器中使用它,但我无法弄清楚它有什么不同。

4

1 回答 1

2

对于给定的控制器操作,#respond_with 根据客户端请求的 mime 类型生成适当的响应。

如果仅使用资源调用该方法,如本例所示 -

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

  def index
    @people = Person.all
    respond_with @people
  end
end

那么响应的 mime 类型通常根据请求的 Accept 标头和先前调用控制器的类方法 respond_to 声明的可用格式集来选择。或者,可以通过在控制器中显式设置 request.format 来选择 mime 类型。

如果未识别出可接受的格式,则应用程序返回“406 - 不可接受”状态。否则,默认响应是呈现以当前操作和所选格式命名的模板,例如 index.html.erb。如果没有可用的模板,则行为取决于所选格式:

对于 html 响应 - 如果请求方法是 get,则会引发异常,但对于其他请求(例如 post),响应取决于资源是否有任何验证错误(即假设已尝试保存资源,例如通过一个创建动作)-

如果没有错误,即资源保存成功,响应重定向到资源,即它的显示动作。

如果存在验证错误,则响应会呈现默认操作,对于 post 请求是 :new 或对于 patch 或 put 是 :edit。

因此,像这样的一个例子 -

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 请求,响应相当于调用渲染 xml: 资源。

于 2013-12-10T11:28:17.380 回答