Rails路线。该流程如何明确地运作?

时间:2013-05-08 23:26:33

标签: ruby-on-rails ruby web-applications

我现在使用Ruby on Rails创建了一些应用程序,但是有一些我无法理解的概念。

其中一个是“路由”流程如何运作?我的意思是,用户输入URL字符串,Rails提供相关资产以响应URL。

以下是我的想法:

  1. 用户使用浏览器浏览服务器:

    http://0.0.0.0:3000
    
  2. 然后他们用字符串前缀他们的URL:

    http://0.0.0.0:3000/entries/view_all
    
  3. Rails的'routes.rb'文件指定字符串应该与指令实际相关的内容:

    match "/entries/view_all" => "entries#view_all"
    
  4. 上面的指令说当字符串“/ entries / view_all”被添加到URL之前时,执行文件'entries_controller.rb'中找到的方法view_all

    < / LI>
  5. 执行view_all方法:

    def view_all
      @entries = Entry.all(:order => 'created_at DESC')
    end
    

    它将表格'Entry'中的所有条目按降序分配给常量@entries

  6. Rails然后神奇地知道为用户提供'view_all.html.erb'。

  7. “view_all.html.erb”中的each循环显示“条目”表中的相关信息:

    <% @entries.each do |entry| %>
    <h1><%= entry.title %></h1> 
    <p><%= entry.content %></p>
    <p><em>Posted at <%= entry.created_at %></em></p>
    <% end %>
    
  8. 我的问题如下:

    1. 我对事物的运作方式有多么错误?
    2. 在上面的第3步中,Rails如何知道在{entries_controller.rb'中找到了view_all方法?该指令为entries#view_all,而非entries#view_all。 Rails是否自动匹配'controllers'目录中控制器文件名的开头,并忽略'_controller.rb'?
    3. 在上面的第6步中,Rails如何神奇地“知道”提供'view_all.html.erb'视图?它与我认为它在问题#2中的作用类似吗? Rails是否匹配文件名的'view_all'部分和'entries_controller.rb'中找到的方法的名称?
    4. 对象/常量@entries及其所有方法如何从'entries_controller.rb'“传递”到'view_all.html.erb'?

3 个答案:

答案 0 :(得分:3)

响应(2)和(3) - Rails强调约定而非配置,这导致路由器,控制器和视图模板之间看似神奇的耦合。例如,路由器知道entries引用EntriesController类,因为ActionDispatch::Routing::RouteSet中有一行:

def controller_reference(controller_param)
  controller_name = "#{controller_param.camelize}Controller"
  ...

这不是魔术 - “控制器”一词是硬编码的。这正是Rails根据您的输入编程所期望的。而且就像在这个地方一样,当你开始使用它时可能会有点令人生畏(看看Ember.js这样的更令人生畏的魔法)。

响应(4):Rails将您的各个实例变量复制到ActionView实例中。社区中是否应该真正做到这一点存在相当大的争议,但是现在它是如何工作的,并且在编写控制器动作时应该记住这一点。在复制视图中不需要的大量或膨胀对象时,您不需要很多开销。

答案 1 :(得分:2)

实际上,你得到了它。它的名字都匹配了。 Entry模型与entries_controller匹配,与entries视图匹配。特定视图的名称与控制器操作相关。

@entries是一个实例变量(称为它是整个模型的一个实例),以及以@开头的任何变量。控制器中的那些变量是相应视图可用的变量。

使用的巧妙技巧是_enrty部分。

<强> _entry.html.erb

<h1><%= entry.title %></h1> 
<p><%= entry.content %></p>
<p><em>Posted at <%= entry.created_at %></em></p>

然后,在您要拨打index的地方(您的view_all通常标记为index)或其中的部分,您可以<%= render @entries %>

但是,轨道的许多魔力都在于匹配的匹配命名约定。有很多方法,因为一切都是可定制的,但总结起来。干杯!

答案 2 :(得分:1)

  

1)我对事物如何运作的概念有多么错误?

这是一个很好的思考过程如何运作的方法

  

2)在步骤(3)中,rails如何实际知道'entries_controller.rb'中的'view_all'方法?该指令是'entries#view_all',而不是'entries#view_all'。 rails是否自动匹配'controllers'目录中控制器文件名的开头,并忽略'_controller.rb'?

Rails遵循一个名为“Convention over configuration”的指令,这意味着只要你按照预期的方式给出指令,Rails就会以某种方式运行。所以在上面的查询中,因为你指定了控制器的“条目”部分,它知道要在“entries_controller”中查看“view_all”动作

  

3)在步骤(6)中,rails如何神奇地知道提供'view_all.html.erb'视图?它与我认为它在问题2中的工作方式类似吗? rails是否匹配文件名的'view_all'部分和'entries_controller.rb'中找到的方法的名称?

约定配置又称“魔术”。 Rails执行操作后,将根据您的请求查找匹配的模板。如果您请求json页面(例如通过更改请求标头),它将查找view.json.erb。如果你遗漏了那个模板,它会抛出一个错误,除非你在动作结束时使用了一个渲染调用来告诉它做其他事情

  

4)对象/常量'@entries'及其所有方法如何从'entries_controller.rb''传递'到'view_all.html.erb'?

它只是:D,或者您是否要求查看对此负责的rails源代码?

ActionView(视图)和ActionController(控制器)都从Actionpack继承,所以我想它并不难以在两者之间共享变量。