1

我不是在问如何使用它们,而是在问它们是如何工作的。我的控制器(刚刚为我的控制器使用了一个脚手架生成器)有一个方法:

def index
  @users = User.all
end

通过该方法,我可以获取 html 响应 (index.html.erb),即使没有在请求中指定“html”,也可以获取 json 响应 (index.json.jbuilder)。

在其他方法中,有format.htmlformat.json。在上面的示例方法index中,没有提到任何一种“类型”的响应。为什么/它是如何工作的?!?

请求 /users - 预期的默认 html

请求 /users.html -- 预期的 html 响应

请求 /users.js - 我取回了 html 内容<body>(也许这是部分内容?)

我没有在任何地方为 .js 指定模板。

请求 /users.txt - 我收到预期的错误消息:

Missing template users/index, application/index with {:locale=>[:en], :formats=>[:text], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder]}.

请求 /users.xml - 我收到了预期的错误消息,即使 xml 看起来比主要资源的 .js 处理程序更实用:

Missing template users/index, application/index with {:locale=>[:en], :formats=>[:xml], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder]}

为什么要处理 .abc 的请求?即使它没有表明它是 html,但它就是这样处理它的。

Started GET "/users.abc" ...
Processing by UsersController#index as

我看到有 :handlers 指定,但没有指定如何/什么应该处理 .js 请求。为什么 .js 请求没有吐出错误?见鬼,这一切在没有 respond_to 块的情况下如何工作?我想我希望默认情况下会使用 html 处理程序,但默认情况下我不希望 .json 响应。通常情况下,我希望能够返回各种格式,有时我宁愿只使用 .json 响应而不是 html 响应。如何/在哪里可以找到处理此问题的文档?它与respond_to 块并没有真正的关系,因为即使没有respond_to,我也会得到多格式输出。

4

2 回答 2

4

在控制器中,当没有定义 mime 类型时,rails 将简单地呈现默认类型:

def index
  @users = User.all
end

相当于

respond_to :html

def index
  @users = User.all
  respond_with @users
end

话虽如此,让我们来看看其他 mime 类型:

请求 /users.js

这个很有趣,看看这里的 rails 代码库,我们可以看到它将使用以下方式渲染模板default_render

# to_js simply tries to render a template. If no template is found, raises the error.
def to_js
  default_render
end

这也是htmlmime 类型的默认情况:

# HTML format does not render the resource, it always attempt to render a
# template.
#
def to_html
  default_render
rescue ActionView::MissingTemplate => e
  # ...
end

一是什么意思?-- 如果定义了 js 模板,rails 会渲染它。否则,它将回退以呈现默认的 html 模板。这就是您获得 .html 内容的原因<body>。看看你的app/views/layouts/application.html.erb文件:

<body>
  <%= yield %>
</body>

请求 /users.txt请求 /users.xml

基本上所有“默认未定义”的 mime 类型都需要您定义一些逻辑以不引发异常。从轨道来源:

def respond
  method = "to_#{format}"
  respond_to?(method) ? send(method) : to_format
end

Rails 默认定义to_htmlto_js. 对于其他 mime 类型,您将需要满足以下方法的条件。对于jsonand ,xml它只是意味着调用或使用。to_jsonto_xmlrespond_to

有关更多信息,请在此处查看responder.rbrails source 中的文件。查看 Rails 源代码以真正了解事物的工作原理总是很好的。当然,有时它需要腾出一些时间并在方法和文件之间跳转。

于 2013-08-10T08:52:03.703 回答
-1

我不确定如果控制器的方法在没有“reposnd_to”块的情况下获取 JS 格式的请求,rails 的反应是什么,但我认为它会以“不可接受的格式”错误回答。所以我认为默认情况下它假定请求是 html 格式,并且要回答 html 以外的内容,您必须使用 respond_to 格式块指出。

该机制如何工作,“rails 从客户端提交的 HTTP Accept 标头确定所需的响应格式”(https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/mime_responds .rb#L85 ) rails 消息来源说。因此,在以 mime 类型生成请求时明确说明了接受的格式

于 2013-08-09T01:41:57.890 回答