有人可以向我解释ActionView模板的工作原理吗?

时间:2013-08-09 00:24:20

标签: ruby-on-rails

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

def index
  @users = User.all
end

从该方法,我可以得到html响应(index.html.erb),即使没有在请求中指定“html”,或者我可以获得json响应(index.json.jbuilder)。

在其他方法中,有format.htmlformat.json。在上面的示例方法index中,没有引用任何“类型”的响应。为什么/如何运作?!?

请求/用户 - 预期默认html

请求/users.html - 预期的HTML回复

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

我没有在任何地方为.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

我看到有:指定了处理程序,但没有指定处理.js请求的方式/内容。为什么.js请求没有吐出错误?天哪,如果没有respond_to阻止,这一切是如何工作的?我想我希望默认使用html处理程序,但我不希望默认情况下使用.json响应。通常情况下,我希望能够返回各种格式,有时候我更喜欢只对html格式的.json响应。我如何/在哪里找到处理此问题的文档?它与respond_to块没有关系,因为即使没有respond_to,我也会得到多格式输出。

2 个答案:

答案 0 :(得分: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代码库[{3}},我们可以看到它将使用default_render呈现模板:

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

这也是html mime类型的默认情况:

# 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模板。这就是你获得<body>的html内容的原因。查看您的app/views/layouts/application.html.erb文件:

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

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

基本上所有“默认情况下未定义”的mime类型都需要你定义一些不抛出异常的逻辑。来自rails来源:

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

Rails默认定义to_htmlto_js。对于其他mime类型,您需要满足here的条件。对于jsonxml,只需要调用to_jsonto_xml或使用respond_to

有关详细信息,请查看rails source following method中的responder.rb文件。看看rails源来真正理解它是如何工作的总是很好的。当然,有时需要花些时间来跳过方法和文件。

答案 1 :(得分:-1)

我不确定如果控制器的方法获得请求,比如说JS格式没有“reposnd_to”块,那么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-type

中生成请求时,会明确声明接受的格式