Pt-E-1
Activity Description
Create a migration that copies the product price into the line item, and add_product method in the Cart model to capture the price whenever a new line item is created.
Author’s Solutions
blah
Readers’ Solutions
Marius says
The migration first: rails generate migration add_product_price_to_line_item price:decimal
class AddProductPriceToLineItem < ActiveRecord::Migration
def self.up
add_column :line_items, :price, :decimal, :precision => 8, :scale => 2
say_with_time "Updating prices..." do
LineItem.find(:all).each do |lineitem|
lineitem.update_attribute :price, lineitem.product.price
end
end
end
def self.down
remove_column :line_items, :price
end
end
In app/models/cart.rb
def add_product(product_id, product_price)
current_item = line_items.where(:product_id => product_id).first
if current_item
current_item.quantity += 1
else
current_item = LineItem.new(:product_id => product_id, :price => product_price)
line_items << current_item
end
current_item
end
In app/controllers/line_items_controller.rb pass product.price as an argument in the Create action:
def create
@cart = current_cart
product = Product.find(params[:product_id])
@line_item = @cart.add_product(product.id, product.price)
session[:counter] = 0
respond_to do |format|
if @line_item.save
format.html { redirect_to(@line_item.cart) }
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
Brent says
The migration should update existing line items price with the product price. The add_product method will only take care of adding new products (after the migration).
Marius says
Thanks. I read over that.
Ken says
Would it also make sense to update app/models/line_item.rb to use the line_item’s price instead of the product’s price? This would make sure you are using the line_item price in the display:
class LineItem < ActiveRecord::Base
belongs_to :product
belongs_to :cart
def total_price
price * quantity
end
end
Doc says
Through unit testing, I found that the price and quantity are not actually updated in the table for data added after the migration. I changed the add_product
method to include a parameter for the current price (defaults to nil
to use the catalog price if current_price
is not provided) and used the update_attributes
method to update the table with the new price and quantity. I chose to update the price any time the line item is changed.
...
def add_product(product_id, current_price = nil)
current_item = line_items.where(:product_id => product_id).first
current_price = Product.find(product_id).price if current_price.nil?
if current_item
current_item.update_attributes
:quantity => current_item.quantity + 1,
:price => current_price
else
current_item = LineItem.new
:product_id => product_id,
:price => current_price
line_items << current_item
end
current_item
end
...
Page History
- V70: Damian Szalbierz [over 1 year ago]
- V69: David Hislop [over 3 years ago]
- V68: David Hislop [over 3 years ago]
- V67: David Hislop [over 3 years ago]
- V66: David Hislop [over 3 years ago]
- V76: Steven Finnegan [over 6 years ago]
- V75: Steven Finnegan [over 6 years ago]
- V74: Steven Finnegan [over 6 years ago]
- V73: Steven Finnegan [over 6 years ago]
- V72: Duccio Armenise - P.IVA 01360060113 [over 6 years ago]