在没有阻止的情况下调用时,respond_to会做什么?

GMA*_*GMA 5 ruby-on-rails response controllers respond-to

我理解respond_to当用这样的东西调用时它是如何工作的:

def index
  @users = User.all
  respond_to do |format|
    format.html
    format.json { render json: @users }
  end
end
Run Code Online (Sandbox Code Playgroud)

但我见过一些respond_to在控制器方法之外传递符号列表的应用程序,例如:

class UsersController < ApplicationController

  respond_to :html, :json

  def index
    # blah blah bah
  end
end
Run Code Online (Sandbox Code Playgroud)

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

Ser*_*sko 2

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

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

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

  def index
    @people = Person.all
    respond_with @people
  end
end
Run Code Online (Sandbox Code Playgroud)

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

如果未识别可接受的格式,应用程序将返回“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
Run Code Online (Sandbox Code Playgroud)

在没有 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
Run Code Online (Sandbox Code Playgroud)

对于 JavaScript 请求 - 如果找不到模板,则会引发异常。

对于其他请求 - 即数据格式,如 xml、json、csv 等,如果传递给 respond_with 的资源响应 to_,该方法会尝试直接以请求的格式呈现资源,例如,对于 xml 请求,响应相当于调用渲染 xml: 资源。