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).
Finishing a Shopping Cart Implementation - Ajax’ing It (Page 3 of 6 )
Tip If you’re looking for a sound introduction to Ajax, consider Foundations of Ajax by Ryan Asleson and Nathaniel T. Schutta (ISBN 1-59059-582-3).
For testing that adding items to the cart works with Ajax, we add another test to our functional test filetest/functional/cart_controller_test.rb:
def test_adding_with_xhr assert_difference(CartItem, :count) do xhr :post, :add, :id => 5 end assert_response :success assert_equal 1, Cart.find(@request.session[:cart_id]).cart_items.size end
You can see that it’s almost identical to thetest_addingtest method, with just two differences:
Instead of calling theposttest helper method, we callxhr(alias forxml_http_request). It simulates an Ajax’ed call to the sameadd action.
We don’t want to be redirected after the action, but instead get a normal 200 HTTP Success response.
To make ouraddcontroller action work correctly with Ajax calls, we need to modifyapp/controllers/cart_controller.rbslightly:
Withrequest.xhr?, we can check if the request was made by Ajax, just as we can check whether a request was done usingPOSTorGET. What we do is pretty much the same as withPOSTrequests. However, since we want the flash message to be accessible only to the current action (and not the next one), we use theflash.nowhash instead of justflash.
pageis an object provided to the template that represents the web page in question. All the changes done to the page are normally done through it.page.replace_htmltakes as its arguments first the DOMidof the element being replaced (here, for example<div id="shopping_cart">) and the value it’s being replaced with. As you can see, you can use partials there just as withrendercalls, as well as simple strings.
Tip You can read more about the Yellow Fade Technique athttp://www.37signals.com/svn/ archives/000558.php.
Using all the attributes makes thelink_to_remotecall a bit messy, so we create our own helper method for this inapp/helpers/application_helper.rb. For the sake of brevity, let’s create similar helpers for removing a book from the cart and clearing the whole cart at the same time, as shown in Listing 5-3. We will use them in the later sections of this chapter.