Ruby-on-Rails

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).

We’re going to use two approaches to implementing the Add Items to the Cart user story. One is the “traditional” way, which takes care of users whose browser doesn’t support JavaScript. The other way will use Ajax techniques to provide a streamlined user interface.

The Traditional Way

We need to implement the action for adding an item to a cart in ourCartController (inapp/controllers/cart_controller.rb), as follows:

The code checks whether the request was an HTTPPOSTorGETrequest and acts on that information. In the case of a formPOST, we add the item, insert a notice to theflashhash, and redirect to the catalog controller. If the user got to the action by clicking a link, we show her a confirmation page with a form that points to the same action.

Createapp/views/cart/add.rhtmland add the following to it to implement the confirmation page:

button_tois a Rails helper that behaves just likelink_to, but instead of an anchor element, it creates an inline form with a single button. When a user clicks this button, she gets to the sameadd action, this time with aPOSTrequest, and will get the new item added to the cart. This might sound awkward, but there are two good reasons to make the application behave like this:

You should never useGET requests (normal links) to change the state of a web application. So-called web accelerators (or link fetchers) often crawl through all the links of a loaded web page and fetch the linked pages while the user is reading the page. If fetching those links would result in adding random items to the shopping cart, we would probably end up with a bunch of less-than-happy customers.

This traditional way to add items to a shopping cart will be visible to only the few customers who are using a browser that doesn’t support JavaScript. In the next section, we will implement an interface that will be used by the vast majority of customers, and that is about gazillion times slicker than the approach described in this section.

Now adding an item to a cart almost works. However, there is noaddmethod in theCartclass, so we need to add it toapp/models/cart.rbbefore we can start filling up the carts.

The idea behind theaddmethod is that if there is already a certain amount of the current book in the cart, we increment that amount by one, using theupdate_attributemethod. If there is no sign of the given book, a new item will be added and its amount will be set to1.

We’re now finished with the old-fashioned way of adding books to the cart. Our test runs fine (try if you don’t believe us), so we can extend our application to work with Ajax.