Moving the Cart

Learn to move the existing cart more efficiently by using partial templates.

Currently, our cart is rendered by the show action in the CartController and the corresponding .html.erb template. We’d like to move that rendering into the sidebar. This means it’ll no longer be in its own page. Instead, we’ll render it in the layout that displays the overall catalog. We can do this using partial templates.

Partial templates

Programming languages let us define methods. A method is a chunk of code with a name. If we invoke the method by the name, the corresponding chunk of code is run. Of course, we can pass parameters to a method as well, which lets us write a piece of code that can be used in many different circumstances.

Think of Rails partial templates (“partials” for short) like a method for views. A partial is simply a chunk of a view in its own separate file. We can invoke (aka “render”) a partial from another template or from a controller, and the partial will render itself and return the results of that rendering. As with methods, we can pass parameters to a partial so the same part can render different results.

We’ll use partials twice in this iteration. First, let’s look at the cart display:

Press + to interact
<article>
<% if notice %>
<aside id="notice"><%= notice %></aside>
<% end %>
<h2>Your Cart</h2>
<table>
<% @cart.line_items.each do |line_item| %>
<tr>
<td class="quantity"><%= line_item.quantity %></td>
<td><%= line_item.product.title %></td>
<td class="price"><%= number_to_currency(line_item.total_price) %></td>
</tr>
<% end %>
<tfoot>
<tr>
<th colspan="2">Total:</th>
<td class="price"><%= number_to_currency(@cart.total_price) %></td>
</tr>
</tfoot>
</table>
<%= button_to 'Empty cart', @cart,
method: :delete,
data: { confirm: 'Are you sure?' } %>
</article>

It creates a list of table rows, one for each item in the cart. Whenever we iterate like this, we should stop and ask “Is this too much logic in a template?” It turns out we can abstract away the loop by using partials. This also sets the stage for some Ajax later.

To do this, we will make use ...