本章内容:
class AddQuantityToLineItems < ActiveRecord::Migration def self.up add_column :line_items, :quantity, :integer, :default => 1 end def self.down remove_column :line_items, :quantity end end
class Cart < ActiveRecord::Base has_many :line_items, :dependent => :destroy def add_product(product_id) current_item = line_items.find_by_product_id(product_id) if current_item current_item.quantity += 1 else current_item = line_items.build(:product_id => product_id) end current_item end end3、修改在线商品控制器,使用第二步定义的add_product方法
def create @cart = current_cart product = Product.find(params[:product_id]) @line_item = @cart.add_product(product.id) respond_to do |format| if @line_item.save format.html { redirect_to(@line_item.cart, :notice => 'Line item was successfully created.') } format.xml { render :xml => @line_item, :status => :created, :location => @line_item } else format.html { render :action => "new" } format.xml { render :xml => @line_item.errors, :status => :unprocessable_entity } end end end修改视图文件,显示信息。
<h2>Your Pragmatic Cart</h2> <ul> <% @cart.line_items.each do |item| %> <li><%= item.quantity %> × <%= item.product.title %></li> <% end %> </ul>此时的显示结果如下所示:
def self.up # replace multiple items for a single product in a cart with a single item Cart.all.each do |cart| # count the number of each product in the cart sums = cart.line_items.group(:product_id).sum(:quantity) sums.each do |product_id, quantity| if quantity > 1 # remove individual items cart.line_items.where(:product_id=>product_id).delete_all # replace with a single item cart.line_items.create(:product_id=>product_id, :quantity=>quantity) end end end end
def self.down # split items with quantity>1 into multiple items LineItem.where("quantity>1").each do |line_item| # add individual items line_item.quantity.times do LineItem.create :cart_id=>line_item.cart_id, :product_id=>line_item.product_id, :quantity=>1 end # remove original item line_item.destroy end end end完成之后通过命令回滚迁移rake db:rollback
def show begin @cart = Cart.find(params[:id]) rescue ActiveRecord::RecordNotFound logger.error "Attempt to access invalid cart #{params[:id]}" redirect_to store_url, :notice => 'Invalid cart' else respond_to do |format| format.html # show.html.erb format.xml { render :xml => @cart } end end end修改之后进行测试,手动输入无效购物车id之后,页面自动跳转,并在页面上给出提示:
<h2>Your Pragmatic Cart</h2> <ul> <% @cart.line_items.each do |item| %> <li><%= item.quantity %> × <%= item.product.title %></li> <% end %> </ul> <%= button_to 'Empty cart', @cart, :method => :delete, :confirm => 'Are you sure?' %>2、修改destroy方法
def destroy @cart = current_cart @cart.destroy session[:cart_id] = nil respond_to do |format| format.html { redirect_to(store_url, :notice => 'Your cart is currently empty') } format.xml { head :ok } end end end现在点击Empty Cart按钮,网页自动回到带有提示信息的目录页面
<div class="cart_title">Your Cart</div> <table> <% @cart.line_items.each do |item| %> <tr> <td><%= item.quantity %>×</td> <td><%= item.product.title %></td> <td class="item_price"><%= number_to_currency(item.total_price) %></td> </tr> <% end %> <tr class="total_line"> <td colspan="2">Total</td> <td class="total_cell"><%= number_to_currency(@cart.total_price) %></td> </tr> </table> <%= button_to 'Empty cart', @cart, :method => :delete, :confirm => 'Are you sure?' %>
为了显示各个在线商品条目价格和购物车中商品总价格,页面代码中调用了item.total_price和@cart.total_price方法。下面分别在line_item和cart模型方法中添加这两种方法。
item.total_price
def total_price product.price * quantity endcart.total_price
def total_price line_items.to_a.sum { |item| item.total_price } end然后在depot.css样式表中添加欲修改的样式
#store .cart_title { font: 120% bold; } #store .item_price, #store .total_line { text-align: right; } #store .total_line .total_cell { font-weight: bold; border-top: 1px solid #595; }章节复习回顾: