Agile Web Development with Rails Translator (16)
8.5 cycle C3: Complete shopping cart
Let's start processing the empty shopping cart connection on the shopping cart display. We know we have to implement a Empty_cart () method within the store "controller". Let's delegate its responsibilities to the cart class.
April 17, 2006 Update
def Empty_cart
find_cart.empty!
Flash[:notice] = ' Your cart is now empty '
Redirect_to (: action = ' index ')
End
Within the cart, we realized the empty! () method.
def empty!
@items = []
@total_price = 0.0
End
Now when we click on the empty shopping cart connection, we will return to the catalog page and display a friendly prompt message.
However, there is one more question. Let's look back at our code and we've introduced two repeating parts.
First, in the store "controller", we now place a message to flash in three places and redirect to the index page. It sounds that we should take the public part of the code into a method, so let's implement the Redirect_to_index () method, and modify the Add_to_cart (), Display_cart (), and Empty_cart () method to use it.
def Add_to_cart
Product = Product.find (Params[:id])
@cart = Find_cart
@cart. Add_product (product)
Redirect_to (: action = ' Display_cart ')
Rescue
Logger.error ("Attempt to access invalid product #{params[:id]}")
Redirect_to_index (' Invalid product ')
End
def Display_cart
@cart = Find_cart
@items = @cart. Items
If @items. Empty?
Redirect_to_index ("Your cart is currently empty")
End
End
def Empty_cart
@cart = Find_cart
@cart. empty!
Redirect_to_index (' Your cart is now empty ')
End
Private
def redirect_to_index (msg = nil)
Flash[:notice] = MSG if MSG
Redirect_to (: action = ' index ')
End
The second repeating part in the cart "model" is two constructors and the empty! method accomplishes the same thing. This is easy to fix-we'll call empty! inside the constructor () method.
DEF initialize
empty!
End
def empty!
@items = []
@total_price = 0.0
End
"Help Method" (Helper)
The second task at this stage is to tidy up the dollar sign displayed in the shopping cart. Turns out to be 59.9, we should show $59.90.
Now we know what to do. We can place the sprintf () method in "View".
<TD align= "Right" >
<%= sprintf ("$%0.2f", Item.unit_price)%>
</td>
But before we do that, let's think about it. We have to show every dollar sign for us to do this. This is a repetition. What if the customer later asked us to insert a comma in a three-digit number, or to indicate negative numbers within a parenthesis? The best way is to format the currency into a single method so that we can make changes only in this place. Before writing the method, we must know where to write the appropriate.
Fortunately, rails has an answer-it lets me define a "help method." This "Help method" is a simple method within a "module" that is automatically included in your view. You define a helper file within the App/helpers directory. A file named Xyz_helper.rb defines a method that is valid for a view called by the XYZ "Controller". If you define a Help method in file App/helpers/application_helper.rb, these methods will work in all views. It seems like a common thing to show US dollar totals, let's add a method to that file.
# The methods added to this helper would be available
# to all templates in the application.
Module Applicationhelper
def fmt_dollars (AMT)
sprintf ("$%0.2f", AMT)
End
End
We will update the "view" of the shopping Cart display page using this new method.
<%
For item in @items
Product = Item.product
-%>
<tr>
<td><%= item.quantity%></td>
<td><%= h (product.title)%></td>
<TD align= "Right" ><%= fmt_dollars (Item.unit_price)%></td>
<TD align= "Right" ><%= fmt_dollars (Item.unit_price * item.quantity)%></td>
</tr>
<% End%>
<tr>
<TD colspan= "3" align= "right" ><strong>Total:</strong></td>
<TD id= "Totalcell" ><%= fmt_dollars (@cart. Total_price)%></td>
</tr>
Now, when I display the shopping cart, the dollar totals seem to be well formatted.
Now is the time for discussion. During this time we wrote this example application, rails released to 1.0. Later, many of the built-in "help methods" for numbers were added. One of these methods is Number_to_currency (), which will replace the Fmt_dollars () method we just wrote. However, if we modify this book using these new methods, we will not be able to show you how to write your own "Help method".
Finally, in the Category catalog page (created by the index.rhtml template) we use sprintf () to format the unit price of the product. Now that we have a more convenient currency formatting tool, we will also use it. We don't show it anymore because the change is too trivial.
What did we just do?
It seemed a busy day, but only one thing was done. We added a shopping cart to our store, and then we used some of the rails features.
1. Use "session" to store the state.
2. Use belogs_to to correlate rails's "model".
3, create and integrate and database "model".
4. Use Flash to pass the error between actions.
5. Remove duplicate code with "Help method".
6. Use logger to record events.
Now the customer wants to see the checkout function. That's the next chapter.