diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 7032afe..bc16723 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,45 +2,17 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - + + + + + + + @@ -52,7 +24,7 @@ - @@ -62,10 +34,10 @@ - - + + - + @@ -74,79 +46,79 @@ - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + @@ -168,22 +140,22 @@ @@ -985,7 +957,11 @@ 1332545195943 1332545195943 - @@ -1012,6 +988,7 @@ + @@ -1026,7 +1003,6 @@ - @@ -1067,7 +1043,7 @@ - + - + + + - + - + + + - + - + + + - + - + - + - + - + - + + + - + + + - + - + - + - + - + - + - + - + - + - + + + - + - + + + - + - + - + - + - + - + diff --git a/app/assets/stylesheets/carts.css.scss b/app/assets/stylesheets/carts.css.scss index 62647c9..88957b6 100644 --- a/app/assets/stylesheets/carts.css.scss +++ b/app/assets/stylesheets/carts.css.scss @@ -1,3 +1,19 @@ // Place all the styles related to the carts controller here. // They will automatically be included in application.css. // You can use Sass (SCSS) here: http://sass-lang.com/ +/* START_HIGHLIGHT */ +.carts { + .cart_title { + font: 120% bold; + } + + .item_price, .total_line { + text-align: right; + } + + .total_line .total_cell { + font-weight: bold; + border-top: 1px solid #595; + } +} +/* END_HIGHLIGHT */ \ No newline at end of file diff --git a/app/controllers/carts_controller.rb b/app/controllers/carts_controller.rb index d39ab43..8b6b75f 100644 --- a/app/controllers/carts_controller.rb +++ b/app/controllers/carts_controller.rb @@ -13,11 +13,16 @@ def index # GET /carts/1 # GET /carts/1.json def show - @cart = Cart.find(params[:id]) - - respond_to do |format| - format.html # show.html.erb - format.json { render json: @cart } + 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.json { render json: @cart } + end end end @@ -72,11 +77,13 @@ def update # DELETE /carts/1 # DELETE /carts/1.json def destroy - @cart = Cart.find(params[:id]) + @cart = current_cart @cart.destroy + session[:cart_id] = nil respond_to do |format| - format.html { redirect_to carts_url } + format.html { redirect_to store_url, + notice: 'Your cart is currently empty' } format.json { head :no_content } end end diff --git a/app/controllers/line_items_controller.rb b/app/controllers/line_items_controller.rb index 316ad1d..854338a 100644 --- a/app/controllers/line_items_controller.rb +++ b/app/controllers/line_items_controller.rb @@ -42,12 +42,12 @@ def edit def create @cart = current_cart product = Product.find(params[:product_id]) - @line_item = @cart.line_items.build(product: product) + @line_item = @cart.add_product(product.id) respond_to do |format| if @line_item.save - session[:counter] = nill - format.html { redirect_to @line_item.cart, notice: 'Line item was successfully created.' } + session[:counter] = nil + format.html { redirect_to @line_item.cart } format.json { render json: @line_item, status: :created, location: @line_item } else format.html { render action: "new" } diff --git a/app/models/cart.rb b/app/models/cart.rb index 27cc3b9..a123095 100644 --- a/app/models/cart.rb +++ b/app/models/cart.rb @@ -1,3 +1,17 @@ class Cart < ActiveRecord::Base has_many :line_items, dependent: :destroy -end + + 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 + def total_price + line_items.to_a.sum { |item| item.total_price } + end + +end \ No newline at end of file diff --git a/app/models/line_item.rb b/app/models/line_item.rb index 2fef8ca..931ae3c 100644 --- a/app/models/line_item.rb +++ b/app/models/line_item.rb @@ -1,4 +1,9 @@ class LineItem < ActiveRecord::Base belongs_to :product belongs_to :cart + + def total_price + product.price * quantity + end + end diff --git a/app/views/carts/show.html.erb b/app/views/carts/show.html.erb index 3ade11f..8dc1427 100644 --- a/app/views/carts/show.html.erb +++ b/app/views/carts/show.html.erb @@ -1,9 +1,20 @@ <% if notice %>

<%= notice %>

<% end %> -

Your Pragmatic Cart

-
    +
    Your Cart
    + <% @cart.line_items.each do |item| %> -
  • <%= item.product.title %>
  • + + + + + <% end %> - + + + + +
    <%= item.quantity %>×<%= item.product.title %><%= number_to_currency(item.total_price) %>
    Total<%= number_to_currency(@cart.total_price) %>
    +<%= button_to 'Empty cart', @cart, method: :delete, + confirm: 'Are you sure?' %> + diff --git a/db/migrate/20120328130343_add_quantity_to_line_items.rb b/db/migrate/20120328130343_add_quantity_to_line_items.rb new file mode 100644 index 0000000..7725339 --- /dev/null +++ b/db/migrate/20120328130343_add_quantity_to_line_items.rb @@ -0,0 +1,5 @@ +class AddQuantityToLineItems < ActiveRecord::Migration + def change + add_column :line_items, :quantity, :integer, default: 1 + end +end diff --git a/db/migrate/20120328135252_combine_items_in_cart.rb b/db/migrate/20120328135252_combine_items_in_cart.rb new file mode 100644 index 0000000..8a04ef1 --- /dev/null +++ b/db/migrate/20120328135252_combine_items_in_cart.rb @@ -0,0 +1,30 @@ +class CombineItemsInCart < ActiveRecord::Migration + def 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 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 diff --git a/db/schema.rb b/db/schema.rb index cedf012..38819cc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120326193046) do +ActiveRecord::Schema.define(:version => 20120328135252) do create_table "carts", :force => true do |t| t.datetime "created_at", :null => false @@ -21,8 +21,9 @@ create_table "line_items", :force => true do |t| t.integer "product_id" t.integer "cart_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "quantity", :default => 1 end create_table "products", :force => true do |t| diff --git a/test/functional/carts_controller_test.rb b/test/functional/carts_controller_test.rb index 54b7ceb..16be61b 100644 --- a/test/functional/carts_controller_test.rb +++ b/test/functional/carts_controller_test.rb @@ -41,9 +41,10 @@ class CartsControllerTest < ActionController::TestCase test "should destroy cart" do assert_difference('Cart.count', -1) do + session[:cart_id] = @cart.id delete :destroy, id: @cart end - assert_redirected_to carts_path + assert_redirected_to store_path end end