嵌入式Ruby中的代码执行顺序是什么?

时间:2012-10-18 08:58:53

标签: ruby-on-rails ruby ruby-on-rails-3 erb

我今天做了一些Ruby on Rails魔术,它在某种程度上有效,但我不知道如何。

我正在编写一个应用程序,它应该在每个页面的顶部都有一个导航栏,所以我写了一个部分,我在默认布局中渲染:

views/layouts/application.html.erb

...
<%= render 'shared/navbar' %>
<%= yield %>
...

但我希望突出显示当前所选部分的链接。我决定每个链接中的一系列if语句都很难看,所以我编写了一个或两个帮助程序来管理导航栏上显示的链接。我会告诉你它们如何工作的详细信息,因为它们现在很简单且不相关,但它们的使用方式如下:

views/shared/_navbar.html.erb

...
<% navbar_manager.each_entry do |entry, active| %>
  <li <% if active %>class="active"<%end%>>
    <%= link_to entry.label, entry.url %>
  </li>
<% end %>
...

现在我只需让navbar_manager知道哪个条目是活动的。操作导航栏与视图紧密相关,因此我决定不在控制器中放置适当的代码,而是在视图文件中执行,如下所示:

views/foo/index.html.erb

<% navbar_manager.set_active_entry(:home) %>
...

一个很大的惊喜:它有效。但现在我想到了它:render 'shared/navbar'出现在yield之前的布局文件中。那么navbar_manager.set_active_entry之前调用navbar_manager.each_entry会怎样?更一般地说:嵌入式Ruby处理的顺序是什么?

如果我很幸运,有没有办法确保我想要的订单?

我正在使用Ruby 1.9.3和Rails 3.2

1 个答案:

答案 0 :(得分:2)

代码执行顺序:

  1. 在调用foo #index时,会从views/foo/index.html.erb文件中准备相应的视图内容。

  2. 处理适当的布局。在这种情况下,将拾取views/layouts/application.html.erb文件进行处理。

  3. 布局中的
  4. <%= render 'shared/navbar' %>语句使其处理navbar部分。此时,要显示的视图内容已经可用(作为上述步骤1的一部分,因此navbar_manager标记了用于突出显示的相应部分。

  5. <%= yield %> statement in the layout插入视图内容(在步骤1和步骤3中处理)。

  6. 显示完整处理的结果。

  7. log/development.log是一个很好的资源,可以看到各种观点和视角。部分被执行。

    以下是我的某个应用中的示例:

    Started GET "/" for 127.0.0.1 at 2012-10-13 14:42:23 -0600
    Processing by DashboardController#welcome as HTML   
    User Load (0.8ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1  User Load (0.8ms)  SELECT `users`.* FROM `users`
    Rendered dashboard/welcome.html.erb within layouts/application (2.6ms)
    Rendered layouts/_navigation.html.erb (1.5ms)
    Rendered layouts/_messages.html.erb (0.2ms)
    SQL (1.4ms)  UPDATE `users` SET `updated_at` = '2012-10-13 20:42:23' WHERE `users`.`id` = 1
    Completed 200 OK in 104ms (Views: 88.6ms | ActiveRecord: 3.1ms)
    

    在此示例中,在调用仪表板#welcome时,首先处理dashboard/welcome.html.erb视图,并在layouts/application内呈现;在完成渲染过程之前,布局还会调用navigationmessages部分。