Home arrow Ruby-on-Rails arrow Finishing a Shopping Cart Implementation

Finishing a Shopping Cart Implementation

In this second part of a two-part series on implementing a shopping cart for an online bookstore, we'll create a floating cart that will show its contents to the user, and set up its capabilities. This article is excerpted from chapter five of the book Practical Rails Projects, written by Eldon Alameda (Apress; ISBN: 1590597818).

Author Info:
By: Apress Publishing
Rating: 5 stars5 stars5 stars5 stars5 stars / 11
June 04, 2010
  1. · Finishing a Shopping Cart Implementation
  2. · Implementing the Add Items to the Cart User Story
  3. · Ajax’ing It
  4. · Drag-and-Drop
  5. · Implementing the Remove Items from the Cart User Story
  6. · Implementing the Clear the Cart User Story

print this article

Finishing a Shopping Cart Implementation
(Page 1 of 6 )

Creating the Views

We want to create a floating cart that will show all the items we have in our shopping cart and will appear on all the catalog pages. Let’s first create a partial called app/views/cart/_cart.rhtml:  

<% if flash[:cart_notice] %>
<%= render :partial => "cart/cart_notice" %>
<% end %>

  <h3>Your Shopping Cart</h3>
<% for item in @cart.cart_items %>
<li id="cart_item_<%= item.book.id %>">
<%= render :partial => "cart/item", :object => item %>
<% end %>
<p id="cart_total"><strong>Total: $<%= sprintf("%0.2f", @cart.total) %>➥</strong></p>

In the partial, we first show a notice if there is something to notify. Then we show every item in the cart. Last, we show the subtotal of the whole cart, formatted withsprintfto always show two decimal places. TheCart class doesn’t have atotal method, so let’s add it toapp/models/cart.rb.

def total

  cart_items.inject(0) {|sum, n| n.price * n.amount + sum}

inject is a method for arrays and other enumerable objects that can be used to calculate sums, factorials, and so on of all the items in the container object. It takes one initial parameter (in our case,0) and passes it as the first block parameter (in our case,sum) for the first iteration. Then it passes each item ofcart_itemsto the block asn, one at a time, updating thesum all the time. After it has gone through all of the items, it returns the final value ofsum.

Although a verbal explanation ofinjectmight sound incomprehensible, it is actually fairly easy to use and often makes using explicit loops obsolete. We could, for example, use the following code to get the same result as we do with one line usinginject:

sum = 0
for item in cart_items
sum =+ item.price * item.amount

From thecart/_cart.rhtmlpartial, you can see that we call two additional partials,cart/_item.rhtmlandcart/_cart_notice.rhtml. Let’s create them at once, too. Create a new fileapp/views/cart/_item.rhtmland add the following to it:

<%= link_to item.book.title, :action => "show",
:controller => "catalog", :id => item.book.id %>
<%= pluralize(item.amount, "pc", "pcs") %>, $<%= sprintf("%0.2f", item.price * item.amount) %>

Theitempartial shows a link to the book details page, the number of this book in the cart, and the total cost for this title. As in Chapter 4, we use thepluralizehelper to choose the singular or plural form of “pc,” depending on the number of items.

Theapp/views/cart/_cart_notice.rhtmlis a one-liner, just showing the possible notice indicating a change in the cart:

<p id="cart_notice"><%= flash[:cart_notice] %></p> 

Now that we have a partial to show on the catalog pages, we need to add it to the layout fileapp/views/layouts/application.rhtml, as shown in Listing 5-1. We also add a few JavaScript include tags to get the power of the Prototype andscript.aculo.usJavaScript libraries that come bundled with Rails (and which we’ll need when we start using Ajax in our application, as described in the upcoming “Implementing the Add Items to the Cart User Story” section).

Listing 5-1. Additions to the Application Layout File

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/ xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<title><%= @page_title || 'Emporium' %></title>
  <%= stylesheet_link_tag "style" %>

  <%= javascript_include_tag :defaults %>

<div id="header">
  <h1 id="logo">Emporium&trade;</h1>
  <h2 id="slogan">Books on Rails</h2>

<div id="menu">
    <li><a href="/admin/author">Authors</a>&nbsp;|&nbsp;</li>
    <li><a href="/admin/publisher">Publishers</a>&nbsp;|&nbsp;</li>
    <li><a href="/admin/book">Books</a>&nbsp;|&nbsp;</li>
    <li><a href="/">Catalog</a>&nbsp;|&nbsp;</li>
    <li><a href="/about">About</a>&nbsp;</li>

<div id="content">
  <%= "<h1>#{@page_title}</h1>" if @page_title %>
  <% if flash[:notice] %>
    <div id="notice">
      <%= flash[:notice] %>
  <% end %>
  <%= yield %>

<% if @cart %>
<div id="shopping_cart">
<%= render :partial => "cart/cart" %> </div>
<% end %>

<div id="footer">
 &copy; 1995-2006 Emporium


We also need to add a link for adding a book to the cart. We do that in thecatalog/_books.rhtmlpartial that is used to show every individual book item on the catalog pages:

<dl id="books">
  <% for book in @books %>
    <dt><%= link_to book.title, :action => "show", :id => book %></dt>
    <% for author in book.authors %>
      <dd><%= author.last_name %>, <%= author.first_name %></dd>
    <% end %>
         <%= link_to "+", :controller => "cart",
                          :action => "add", :id => book %>
<dd><small>Publisher: <%= book.publisher.name %></small></dd>
  <% end %>

To make our shopping cart float on the catalog pages and look a bit nicer, we need to add some CSS rules to thestyle.cssstyle sheet, as shown in Listing 5-2.

Listing 5-2. Additions to the Style Sheet

#shopping_cart {
  border-left: 3px solid #666;
  background: #aaa;
  position: fixed;
  bottom: 0;
  right: 0;
  width: 200px;
  height: 100%;
  padding: 5px 10px;

#shopping_cart ul,
#shopping_cart li {
  list-style: none;
  margin: 0;
  padding: 0;

#shopping_cart h3 {
  padding-top: 4em;

#cart_notice {
  border: 2px solid #58A986;
  background: #B2FFD3;
  padding: 3px;
  position: absolute;
  top: 0;
  left: 10px;

body {
  background-color: #fff; color: #333;
  margin-right: 230px;

Notice the use of fixed positioning to make the shopping cart always appear “above the fold.” Now you can open the catalog index page in the browser, and it should look like Figure 5-1.

Figure 5-1.  Book catalog page with sjopping cart

Implementing the User Stories

With our shopping cart set up for action, we’re ready to start implementing our user stories. Of course, we start with adding items.

blog comments powered by Disqus

- Ruby-on-Rails Faces Second Security Flaw in ...
- Ruby 2.0 Prepped for February 2013 Release
- Why LinkedIn Switched from Ruby on Rails
- Adding Style with Action Pack
- Handling HTML in Templates with Action Pack
- Filters, Controllers and Helpers in Action P...
- Action Pack and Controller Filters
- Action Pack Categories and Events
- Logging Out, Events and Templates with Actio...
- Action Pack Sessions and Architecture
- More on Action Pack Partial Templates
- Action Pack Partial Templates
- Displaying Error Messages with the Action Pa...
- Action Pack Request Parameters
- Creating an Action Pack Registration Form

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 

Developer Shed Affiliates


© 2003-2019 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials