Rails:路由,控制器,视图,哦我的(感叹号)

时间:2013-04-20 01:39:49

标签: ruby-on-rails methods

我对RoR场景有点新鲜......我现在才开始连接点。在你的发展生涯中,你们能给我一些更明确的指导和指导吗?

我无法理解路由,控制器和视图之间的相关性(以及它们如何相互连接)。

所以,我的控制器包含indexshownewcreatedestroy方法。和相应的

GET    /entries(.:format)                     entries#index
POST   /entries(.:format)                     entries#create
GET    /entries/new(.:format)                 entries#new
GET    /entries/:id/edit(.:format)            entries#edit
GET    /entries/:id(.:format)                 entries#show
PUT    /entries/:id(.:format)                 entries#update
DELETE /entries/:id(.:format)                 entries#destroy

例如,如果我添加新方法vote_upvote_down以及具有匹配操作名称的视图,它怎么会起作用。

1)添加新操作并将其连接到视图的正确方法是什么? 2) Bonus 使这些方法与ajax兼容的正确方法是什么(用ajax渲染部分)?如果用户没有启用js会发生什么?

我可以根据我得到的答案扩展/发展这个问题。

我已经厌倦了搜索自定义动作路线之类的东西来躲避我的应用程序。它正在流失和糟糕的形式,我终于达到理解语言的水平 - 我已经100%自学了...所以请尽量理解你是否可以为一个年轻的padawan。

3 个答案:

答案 0 :(得分:6)

以下是从头开始思考的方法:

1)您的应用所做的唯一事情是响应HTTP请求。

最典型的请求是:

  • GET - 用户在浏览器的网址栏中输入内容并点击输入。

  • POST - 用户提交表单。

还有其他类型的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

这告诉路由器,如果有人向/things/123/vote_up发出GET请求,则应该触发ThingsController vote_up操作。

所有这些都在Rails Guide中详细阐述,你应该阅读整篇文章。

3)您的控制人员的工作是发送对请求的回复。

通常这意味着从数据库加载记录并渲染该记录的视图。

每个控制器操作都通过将响应发送回传入请求而结束。此响应可以是render调用 - 这意味着以某种格式发回一些数据 - 或redirect调用 - 这基本上会为您发出新请求,因此您可以获得该其他请求的响应

在Rails中,重定向实际上是将请求发送到不同的控制器操作。

渲染调用将数据作为对请求的响应发送。

当您致电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>'

看看会发生什么。

在回复(渲染)时,您可以发送&#34;正常&#34; HTML模板,其中包含整页信息(头部,正文等),或者是Ajax使用的部分信息。您还可以发送原始数据,如JSON或XML。它实际上只是文本,并且取决于该文本的内容(以及随其附带的HTTP标头),浏览器,脚本或客户端应用程序会相应地处理它。

再次,请参阅Rails Guide

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帮助程序。如果你已经创建了如前所示的路线和动作,那就在你的&#34;展示事物&#34;页面你可以有这样的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方法。

你做什么INSIDE你的控制器动作决定你是否准备好响应javascript或html请求等。

虽然rails肯定能够在单个控制器动作中处理多种请求格式,但是使用respond_to块,作为一个实际问题,我发现当你选择路由只响应一个时,事情会更顺利格式或其他。

IE:我会让你的正常页面加载请求(索引,显示,新建,编辑)只是HTML请求,然后我会让你想要添加的任何其他AJAX操作只是Javascript - 即。他们用JSON而不是HTML回应。当然,你不必这样做,但如果你这样做,你的生活会更容易。

我希望这能让您更清楚地了解应用中发生的情况。欢迎来到Rails,您加入了一个伟大的社区!

答案 1 :(得分:2)

欢迎来到ROR世界。 :)

路由,控制器和视图协同工作,将HTTP请求转换为某种响应(无论是HTML,JSON还是XML)。每个人都会攻击不同的问题。

从最后开始,views是rails世界中的模板,通常为ERB。 ERB只是一个模板系统,其他也可以使用,如haml。他们的工作是获取控制器提供给他们的一些数据并生成格式化输出,通常也是HTML,JSON或XML。

但是,您如何知道为特定请求呈现哪个视图?如何将数据输入到您的视图中,以便它可以完成您需要的所有花哨的动态内容?这是控制器进来的地方。Controllers是ruby类,其工作是检查解析的 HTTP请求和任何相关参数,从数据库(或任何地方)获取数据,然后传递数据到视图。控制器通常具有若干不同的方法,每个方法对应于不同的任务(例如,创建,显示,更新等)。

最后,Routes是用于解析HTTP请求并将解析的HTTP请求分派给特定控制器方法的DSL。它们是Rails用于将URL路由到方法的粘合剂,因此名称为routes

关于您的具体问题:

1)要创建新操作,您必须添加路径,控制器方法和视图。因此,例如,如果您想获得条目的计数,您可以添加如下路线:

get '/entries/count' => "entries#count"

这告诉ROR在收到该URL时调用count控制器中的entries方法。在这种情况下,您的控制器方法将是简单的:

def count
   @cnt = Entries.count
end

然后,你会在app/views/entries/count.html.erb中创建一个类似于:

的视图
<p>Count: <%= @cnt %></p>

2)Ajax兼容代码实际上只是一种问“如果请求的请求格式是JSON会怎样?”的方法。为此,您需要使用respond_to方法。在某种程度上,respond_to是指定不同视图以处理请求格式的正式方式。要继续上面的示例,您可以执行以下操作:

def count
  @cnt = Entries.count
  respond_to do |fmt|
    fmt.html # This just renders the default template
    fmt.json { render json: { count: @cnt } }
  end
end

N.b。 - 以上所有代码都是免费的。 :)

答案 2 :(得分:0)

如果你有RESTful控制器:

resources :entries do
  collection do
    get :vote_down
    get :vote_up
  end
end

这将产生另外两条路线:

GET    /entries/:id/vote_up(.:format)                 entries#vote_up
GET    /entries/:id/vote_down(.:format)               entries#vote_down

您可以轻松地将HTTP方法更改为GET,POST,PUT和DELETE。

另外,请检查路线文档中的“Adding More RESTful Actions”。