延續上一篇為購物車加入錯誤處理,本篇實作兩項實用功能:清空購物車與金額顯示格式化。
首先在 store_controller.rb 新增 empty_cart 動作:
def empty_cart find_cart.empty! flash[:notice] = 'Your cart is now empty' redirect_to(:action => 'index') end
再修改 cart.rb 的 empty! 方法,重設項目陣列與總價:
def empty! @items = [] @total_price = 0.0 end
點擊「Empty cart」連結即可清空購物車並導回首頁顯示提示訊息。
觀察到控制器中多處使用 flash[:notice] 並導向 index,屬於代碼壞味道。採用 Extract Method 重構,新增 redirect_to_index 私有方法:
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]}")
flash[:notice] = 'Invalid product'
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
find_cart.empty!
redirect_to_index('Your cart is now empty')
end
def redirect_to_index(msg = nil)
flash[:notice] = msg
redirect_to(:action => 'index')
end
同理,cart.rb 的 initialize 直接呼叫 empty! 避免重複初始化邏輯:
def empty! @items = [] @total_price = 0.0 end def initialize empty! end
在 app/helpers/application_helper.rb 定義 fmt_dollars 方法,統一貨幣顯示格式:
def fmt_dollars(amt)
sprintf("$%0.2f", amt)
end
修改 display_cart.rhtml,將原始數值替換為格式化後的輸出:
<td align="right"><%= fmt_dollars(item.unit_price) %></td> <td align="right"><%= fmt_dollars(item.unit_price * item.quantity) %></td> <td id="totalcell"><%= fmt_dollars(@cart.total_price) %></td>
完成後購物車頁面將以標準貨幣格式顯示單價、小計與總計(如下圖)。
