2

我今天做了一点 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

4

1 回答 1

2

代码执行顺序:

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

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

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

  4. <%= yield %>布局中的语句插入视图内容(在步骤 1 和步骤 3 中处理)。

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

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)

在这个例子中,在调用 dashboard#welcome 时,dashboard/welcome.html.erb首先处理视图,然后在layouts/application; 在完成渲染过程之前,布局也会调用navigation和局部化。messages

于 2012-10-18T16:02:34.423 回答