首页
>
Web开发,
动态语言,
挨踢(IT) > 《Agile Web Development with Rails》抄书笔记(13):清空购物车
《Agile Web Development with Rails》抄书笔记(13):清空购物车
《Agile Web Development with Rails》抄书笔记系列
“《Agile Web Development with Rails》抄书笔记系列”目录
上一节,我们介绍了如何进行错误处理。另外,既然可以向购物车中添加商品,那么清空购物车也是一个必要的功能。我们这节来实现清空购物车的功能。
D呱呱
关于这节内容的代码:
- 这节开始之前:https://github.com/diguage/depot/tree/v-10.2
- 这节完成之后:https://github.com/diguage/depot/tree/v-10.3
要实现清空购物车的功能,那么我们必须向购物车页面添加一个链接,同时修改CartsController的destroy()方法来清除会话。让我们从修改模板开始,这里还是要使用button_to()向页面上添加按钮。
02 | < p id = "notice" ><%= notice %></ p > |
05 | < h2 >Your Pragmatic Cart</ h2 > |
08 | <% @cart.line_items.each do |item| %> |
09 | < li ><%= item.quantity %>×<%= item.product.title %></ li > |
13 | <%= button_to 'Empty cart', @cart, method: :delete, |
14 | data:{ confirm: 'Are you sure?' } %> |
修改CartsController中的destroy(),来确保用户删除了自己的购物车,同时将购物车中会话中删除。删除后,重定向到网店首页,同时给出一个提示信息。
06 | session[ :cart_id ] = nil |
08 | respond_to do |format| |
09 | format.html { redirect_to store_url, |
10 | notice: 'Your cart is currently empty' } |
11 | format.json { head :no_content } |
同时,我们还要更新相应的测试代码,%depot%/test/functional/carts_controller_test.rb.
1 | test "should destroy cart" do |
2 | assert_difference( 'Cart.count' , - 1 ) do |
3 | session[ :cart_id ] = @cart .id |
4 | delete :destroy , id: @cart |
7 | assert_redirected_to store_path |
现在,我们可以看一下购物车页面,然后点击 Emptycart按钮,页面就会被重定向到商品目录页面。同时,还有一个友好的提示信息。如下图:

我还需要添加商品时显示的删除闪存(flash)信息:
05 | product = Product.find(params[ :product_id ]) |
06 | @line_item = @cart .add_product(product.id) |
08 | respond_to do |format| |
10 | format.html { redirect_to @line_item .cart } |
11 | format.json { render json: @line_item , status: :created , location: @line_item } |
13 | format.html { render action: "new" } |
14 | format.json { render json: @line_item .errors, status: :unprocessable_entity } |
最后,我们来重点关注一下购物车的展示。我们使用<table>标签来代替<li>标签。另外,还是使用CSS来确定展示样式。修改后,代码如下:
02 | < p id = "notice" ><%= notice %></ p > |
05 | < div class = "cart_title" >Your Cart</ div > |
07 | <% @cart.line_items.each do |item| %> |
09 | < td ><%= item.quantity %>×</ td > |
10 | < td ><%= item.product.title %></ td > |
11 | < td class = "item_price" ><%= number_to_currency(item.total_price) %></ td > |
14 | < tr class = "total_line" > |
15 | < td colspan = "2" >Total</ td > |
16 | < td class = "total_cell" ><%= number_to_currency(@cart.total_price) %></ td > |
20 | <%= button_to 'Empty cart', @cart, method: :delete, |
21 | data:{ confirm: 'Are you sure?' } %> |
为了能使上述代码工作,我们还需要向LineItem和Cart中分别增加一个方法,用于计算当个商品的总价格以及购物车的总价合计。我们先来修改LineItem,这个计算只是简单的数量乘单价。代码如下:
3 | product.price * quantity |
在Cart,我们使用Rails的Array::sum()方法来对每种商品的总计价格再求和。代码如下:
3 | line_items.to_a.sum {|item| item.total_price } |
接着,我们需要在carts.css.scss中添加一小段样式定义。代码如下:
01 | // Place all the styles related to the carts controller here. |
02 | // They will automatically be included in application.css. |
10 | .item_price, .total_line { |
14 | .total_line .total_cell { |
16 | border-top : 1px solid #595 ; |
预编译后,打开购物车页面,你将看到如下漂亮的页面:

总结
本节内容,再加上前两节内容是一个迭代,对应书中第十章内容。现在,我们的购物车页面总算可以拿得出手了。来让我们看看这个迭代,我们完成了那些工作。
- 向既有表中增加了一列,同时设定了默认值;
- 将数据库中已有的数据按照新的表结构进行迁移;
- 当检查到数据时,给出一个友好提示;
- 使用logger记录日志;
- 删除一条记录;
- 使用CSS调整一个表格的展示;
但是,当我们完成这些功能是,我们的客户拿过来两本杂志,《信息技术(Information Technology)》和《高尔夫周刊(Golf Weekly)》。里面有篇介绍新的网页页面风格的文章,它可以动态更新页面内容,Ajax,她指出。看来,我们下次需要使用这种技术来重构我们的页面。