从一开始就是这样想的:
1) 您的应用程序所做的唯一一件事就是响应 HTTP 请求。
最典型的请求类型是:
还有其他类型的 HTTP 请求,最重要的是 PUT、PATCH 和 DELETE。Rails 遵循 REST 模式,这意味着它为这些 HTTP 动词分配了特定的含义。
2)当任何请求进入您的应用程序时,必须将其路由到控制器操作。
您的routes.rb
文件是 Rails 路由器 (ActionDispatch) 的一组指令,它告诉路由器将请求发送到哪里。“标准”rails 资源作为快捷方式给出,如下所示:
resources :things
这意味着以下内容:
GET /things => things#index
GET /things/:id => things#show
GET /things/new => things#new
GET /things/edit/:id => things#edit
POST /things => things#create
PUT /things/:id => things#update
DELETE /things/:id => things#destroy
这些被认为是标准的 RESTful 操作 - 您的resources :things
声明没有设置其他任何内容。因此,如果您希望控制器执行其他非标准操作,则必须手动添加它们。
如果要对特定记录执行操作,最好的方法是使用:
resources :things do
member do
get 'vote_up'
end
end
这告诉路由器,如果有人向它发出 GET 请求/things/123/vote_up
,它应该触发该ThingsController
vote_up
操作。
所有这些都在Rails 指南中详细说明,您应该阅读整个内容。
3)您的控制器的工作是发送对请求的响应。
通常这意味着从数据库中加载一条记录并呈现该记录的视图。
每个控制器操作都通过将响应发送回传入请求来结束。这个响应可以是一个render
调用——这意味着以某种格式发回一些数据——或者一个redirect
调用——它基本上为你提出一个新的请求,因此你得到另一个请求的响应。
在 Rails 中,重定向实际上是将请求发送到不同的控制器操作。
Render 调用发送数据作为对请求的响应。
当您调用 时render :new
,这是 的快捷方式render :template => :new
,它加载app/views/things/new.html.erb
(或其他)模板,将来自控制器(通常是您的实例变量)的数据发送给它,并使用模板语言(erb、haml 等)对其进行评估。这导致一大串 HTML,然后控制器将其传递给浏览器。
想亲眼看看这是什么?尝试用 结束控制器render :text => 'Hello World'
,甚至:
render :inline => '<!DOCTYPE html><head><title>Inline Wow!</title></head><body>Mind blown.</body></html>'
走着瞧吧。
响应(呈现)时,您可以发送“普通”HTML 模板,其中包含整个页面的信息(头部、正文等),或者 Ajax 使用的部分信息。您还可以发送原始数据,例如 JSON 或 XML。它实际上只是文本,并且根据该文本的内容(以及随之而来的 HTTP 标头),浏览器、脚本或客户端应用程序会相应地处理它。
再次,请参阅Rails 指南。
4) 当浏览器发出请求时,您可能想要发回 HTML。如果请求是由 Ajax 发出的,您可能想要发回 JSON。
对于像您这样的自定义操作,vote_up
您可能根本不想显示模板,而只是重定向。所以,你可能有这样的事情:
ThingsController < ApplicationController
def vote_up
@thing = Thing.find(params[:id])
@thing.vote_up
redirect_to @thing
end
end
现在,路由器的好处之一是它会为您提供 URL 助手。如果您已经创建了如前所示的路由和操作,那么在您的“show thing”页面上,您可能会有这样的 URL:
link_to 'Vote up this thing!', vote_up_thing_path(@thing)
这将创建一个到 的链接things/123/vote_up
,如果有人单击它,它将在 上的vote_up
操作中运行代码ThingsController
,然后重定向回显示事物视图。
5) 您的模板使用链接和表单向控制器发送消息。链接发出 GET 请求,表单发出 POST 请求。
如果你想开始有 AJAX 请求,那很好。在这种情况下,您只需要在 Javascript 中发出请求并处理响应。因此,例如,您可以在模板中添加如下内容:
= link_to 'Vote up this thing', vote_up_thing_path(@thing), :id => 'vote-up-button'
然后在 Javascript(使用 jQuery)中,你可以有这样的函数:
$(function(){
$('a#vote-up-button').click( function(event){
event.preventDefault();
$.ajax({
url: this.attr('href'),
type: 'GET',
success: function(){...},
error: function(){...}
});
});
});
在这种情况下,jQuery Ajax 方法只是发出一个 get 请求,然后根据它得到的响应运行一个回调函数。
6) 你的控制器/路由的结构不会影响你可以发出什么样的请求,只有什么动作会响应什么 URL 上的什么 HTTP 方法。
您在控制器操作中执行的操作决定了您是否准备好响应 javascript 或 html 请求等。
虽然 rails 确实能够在单个控制器操作中处理多种请求格式,但使用respond_to
块,出于实用性的考虑,我发现当您选择让路由仅响应一种或另一种格式时,事情会更加顺利。
IE:我会让你的正常页面加载请求(索引、显示、新建、编辑)只是 HTML 请求,然后我会让你想要添加的任何其他 AJAX 操作仅是 Javascript —— 即。他们用 JSON 而不是 HTML 来响应。当然,您不必这样做,但如果这样做,您的生活会更轻松。
我希望这能让您更清楚地了解您的应用程序中发生了什么。欢迎使用 Rails,您正在加入一个很棒的社区!