如何从另一个局部布局内部正确渲染部分布局中的集合?

时间:2012-05-23 10:42:48

标签: ruby-on-rails partial yield

我有一个购物车,我想在我的应用程序中以3种不同的方式呈现。

  1. 在侧边栏中。仅显示购物车中的商品数量及其总价格。
  2. 在购物车主视图中。显示包含每个商品的产品,数量和总价的链接的订单项。还显示用于增加/减少项目数量的按钮和用于从购物车中删除项目的按钮。
  3. 在订单视图中,以与主购物车视图相同的方式显示购物车内容,但产品链接,更改数量的按钮和“删除”按钮除外。
  4. 到目前为止,我像这样渲染购物车:

    carts/_cart.html.erb

    <%= yield %>
    

    购物车侧边栏布局carts/_sidebar.html.erb

    <ul>
      <li class="nav-header">Your Cart (<%= pluralize(@cart.total_items, "Item") %>)</li>
      <li>Total Due: <%= number_to_euro(@cart.total_price) %></li>
      <% unless @cart.line_items.empty? %>
      <li><%= link_to "View Cart & Checkout", cart_path(@cart) %></li>
      <li><%= link_to "Empty Cart", @cart, :method => :delete %></li>
      <% end %>
    </ul>
    

    通过layouts/_sidebar.html.erb

    <%= render :partial => 'carts/cart', :layout => 'carts/sidebar' %>呈现的内容

    购物车主要布局carts/_main.html.erb

    <table>
      <tr>
        <th>Product</th>
        <th>Quantity</th>
        <th>Price</th>
        <th>Subtotal</th>
        <th></th>
      </tr>
      <%= render @line_items %>
      <tr id="total_line">
        <td colspan="3">Total:</td>
        <td><%= number_to_euro(@cart.total_price) %></td>
        <td></td>
      </tr>
    </table>
    

    carts/show.html.erb

    呈现的内容
    <h1><%= pluralize(@cart.total_items, "Item") %> in Your Cart</h1>
    <%= render :partial => 'cart/cart', :layout => 'carts/main' %>
    <%= link_to "Empty Cart", @cart, :method => :delete %>
    <%= link_to "Checkout", new_order_path %>
    

    还有carts/_order.html.erb当前从orders/new.html.erb以与购物车主视图中相同的方式呈现。

    我想要做的是创建2个不同的布局来渲染来自carts/show.html.erborders/new.html.erb的订单项。为此,我在<%= yield %>

    line_items/_line_item.html.erb

    购物车主要布局line_items/_main.html.erb

    的订单项布局
    <tr>
      <td><%= link_to "#{line_item.product.brand.name} #{line_item.product.title}", product_path(line_item.product) %></td>
      <td>
        <%= link_to "-", decrement_line_item_path(line_item), :method => :post %>
        <%= line_item.quantity %>
        <%= link_to "+", increment_line_item_path(line_item), :method => :post %>
      </td>
      <td><%= number_to_euro(line_item.product.price) %></td>
      <td><%= number_to_euro(line_item.total_price) %></td>
      <td><%= link_to "Remove"), line_item, :method => :delete %></td>
    </tr>
    

    新订单视图line_items/_order.html.erb

    的类似订单项布局
    <tr>
      <td><%= "#{line_item.product.brand.name} #{line_item.product.title}" %></td>
      <td><%= line_item.quantity %></td>
      <td><%= number_to_euro(line_item.product.price) %></td>
      <td><%= number_to_euro(line_item.total_price) %></td>
    </tr>
    

    这是问题的开始。我不明白如何渲染集合。我尝试像这样从carts/_main.html.erb渲染订单项

    <%= render :partial => 'line_items/line_item', :layout => 'line_items/main', :collection => @line_items %>
    

    来自carts/_order.html.erb就像这样

    <%= render :partial => 'line_items/line_item', :layout => 'line_items/order', :collection => @line_items %>
    

    但是我在Carts#show

    中得到了LocalJumpError
    Showing app/views/line_items/_line_item.html.erb where line #1 raised:
    
    no block given (yield)
    

    任何其他:集合名称根本不呈现任何内容。我做错了什么?

1 个答案:

答案 0 :(得分:1)

好的,我明白我做错了什么。首先,错误消息no block given (yield)意味着没有任何东西可以产生。第二,在这种情况下,在渲染部分时不需要使用:布局。

要从layouts/_sidebar.html.erb呈现购物车,只需致电<%= render :partial => 'carts/sidebar' %>

有一件事我不知道。使用集合渲染部分时,部分名称的第二部分将成为该集合中的局部变量名称。

这是主推车视图(carts/_cart.html.erb)的部分内容:

<table>
  <tr>
    <td>Product</th>
    <td>Price</th>
    <td>Quantity</th>
    <td>Subtotal</th>
    <td></th>
  </tr>
  <%= render :partial => 'line_items/cart_item', :collection => @line_items %>
  <tr>
    <td colspan="3">Total:</td>
    <td><%= number_to_euro(@cart.total_price) %></td>
    <td></td>
  </tr>
</table>

哪些可以由<%= render @cart %>呈现。请注意/cart_item名称中的:partial部分。这就是我们在line_items/_cart_item.html.erb中引用集合项的方式:

<tr>
  <td><%= link_to "#{cart_item.product.brand.name} #{cart_item.product.title}", product_path(cart_item.product) %></td>
  <td><%= number_to_euro(cart_item.product.price) %></td>
  <td>
    <%= link_to "-"), decrement_line_item_path(cart_item), :method => :post %>
    <%= cart_item.quantity %>
    <%= link_to "+"), increment_line_item_path(cart_item), :method => :post %>
  </td>
  <td><%= number_to_euro(cart_item.total_price) %></td>
  <td><%= link_to "Remove"), cart_item, :method => :delete %></td>
</tr>

与Orders控制器中显示的购物车相同。 carts/_order.html.erb

...
<%= render :partial => 'line_items/order_item', :collection => @line_items %>
...

line_items/_order_item.html.erb

<tr>
  <td><%= "#{order_item.product.brand.name} #{order_item.product.title}"%></td>
  <td><%= number_to_euro(order_item.product.price) %></td>
  <td>&times; <%= order_item.quantity %></td>
  <td><%= number_to_euro(order_item.total_price) %></td>
  <td></td>
</tr>

希望一切都有意义。