0

我有一个简短的问题可以帮助我理解 Rails 部分。我是 RoR 的新手,刚刚使用 Rails 进行敏捷 Web 开发。如果你有同一本书,我在迭代 F1。

当我不使用部分时,购物车中的 show.html.erb 如下所示:

<% if notice %>
<p id="notice"><%= notice %></p>
<% end %>

<!-- START_HIGHLIGHT -->
<h2>Your Cart</h2>
<table>
<!-- END_HIGHLIGHT -->
  <% @cart.line_items.each do |item| %>
<!-- START_HIGHLIGHT -->
    <tr>
      <td><%= item.quantity %>&times;</td>
      <td><%= item.product.title %></td>
      <td class="item_price"><%= number_to_currency(item.total_price) %></td>
    </tr>
<!-- END_HIGHLIGHT -->
  <% end %>
<!-- START_HIGHLIGHT -->
  <tr class="total_line">
    <td colspan="2">Total</td>
    <td class="total_cell"><%= number_to_currency(@cart.total_price) %></td>
  </tr>
<!-- END_HIGHLIGHT -->
<!-- START_HIGHLIGHT -->
</table>
<!-- END_HIGHLIGHT -->

<%= button_to 'Empty cart', @cart, method: :delete,
    data: { confirm: 'Are you sure?' } %>

然后,当我开始使用 partials 时,我创建了一个名为 _cart.html.erb 的类并将其放入其中:

<h2>Your Cart</h2>
<table>
  <%= render(cart.line_items) %>

  <tr class="total_line">
    <td colspan="2">Total</td>
    <td class="total_cell"><%= number_to_currency(cart.total_price) %></td>
  </tr>

</table>

<%= button_to 'Empty cart', cart, method: :delete, data: { confirm: 'Are you sure?' } %>

并将我的 show.html.erb 修改为:

<% if notice %>
    <p id="notice"><%= notice %></p>
<% end %>

  <%= render(@cart) %>

所以,我现在的困惑是,当我没有部分时,为什么我必须使用 @cart.something 。据我了解,我使用的是名为 carts.rb 的模型。那么,当我创建一个部分时,我只是简单地使用购物车而不是 @cart 并且部分仍在使用模型?

但是为什么我使用渲染(@cart)?那么这个命令是否只使用我的部分 _cart.html.erb?任何人都可以帮助我完成对它的理解吗?可能是这样,但我现在有点困惑:)

4

1 回答 1

2

当您说render(@cart)时,幕后真正发生的事情是 Rails 根据Rails 通常如何工作的约定为您做出了很多假设。

让我们从@cart变量开始。这是一个实例变量,它是一个可供控制器内部任何东西访问的变量。视图与控制器有特殊的关系,因此在控制器方法中定义的实例变量在视图中是可用的。

可以在你的部分中使用@cart,在这种情况下一切都会正常工作。但这通常是一个坏主意 - 您希望部分可在不同位置重用,并假设存在实例变量会在控制器和部分之间引入耦合。

Rails 提供的解决方案是将局部变量传递给局部变量的能力。还记得我说过那render(@cart)是捷径吗?幕后真正发生的事情是这样的:

render partial: 'carts/cart', locals: { cart: @cart }

因为您遵循 Rails 约定,Rails 可以做出以下假设:

  • a 的部分Cart位于app/views/carts/_cart.html.erb
  • 该部分将使用一个名为 的局部变量cart,该变量将传递给该方法。

因此,结果如下:

render @cart

与上面更详细的行具有相同的效果。

于 2013-08-22T10:54:59.533 回答