views:

386

answers:

2

I am trying to build a simple shopping cart with rails, now I am able to add products to cart, I want to know how can I edit products while they are in cart, I am using sessions to control the products in shopping cart. here is what the user see when add to cart :

<% @cart.items.each do |item| %>
<tr>
    <td>
        <%= image_tag item.pic , :alt => "#{item.title}" %>
    </td>
    <td>
        <%= link_to "#{item.title}" , store_path(item.product_id) %>
    </td>
    <td>
        <%= item.unit_price %>
    </td>
    <td>
        <%= item.quantity %>
    </td>
    <td>
        <%= item.total_price %>
    </td>
    <% end %>
</tr>

and this is CartItem class :

class CartItem

  attr_reader :product, :quantity

  def initialize(product)
    @product = product
    @quantity = 1
  end

  def increment_quantity
    @quantity += 1
  end

  def product_id
    @product.id
  end

  def title
    @product.name
  end

  def pic
    @pic = @product.photo.url(:thumb)
  end

  def unit_price
    @product.price
  end

  def total_price
    @product.price * @quantity
  end

end

I want to give the user this ability to edit the quantity of products or remove a product, not only clear the whole cart. how can i do that ?

A: 

Well, you already have something setup in a close manner. You have the increment_quantity method within your cart item model, so what you would need to do is setup the cart model to allow you to specify a product, and then call a new method, like so:

cart.rb (assuming this is your cart model)

def increment_product_quantity(id, quantity)
   product_to_increment = @items.select{|product| product.product_id == id}

   # We do this because select will return an array
   unless product_to_increment.empty?
      product_to_increment = product_to_increment.first
   else
      # your error handling here
   end

   product_to_increment.quantity = quantity
end

def remove_product(id)
   @items.delete_if {|product| product.product_id == id }
end

Now, you will have to modify your cart item model to where quantity is not an attr_reader object, but an attr_accessor object, or create a method for cart items specifically to where you set the quantity; your choice.

There are a few other things which could be done, but this is roughly the easiest and cleanest method that I can recommend right now.

Eric
Would I need to add a new controller action (i.e. Edit_Cart)? Or does it make more sense to add the edits on my add_to_cart action?
JZ
A: 

Nice Question. I was able to get the delete function to work. It looks like you are following the pragmatic programmers Agile Web Development with Rails, Third Edition book.

Here we go...

To add_to_cart.html.erb

I added the following table row, beside the last tr line item:

<td><%= link_to 'remove', {:controller => 'inventories', :action => 'remove_cart_item', :id => "#{item.getinventoryid}"} %></td>

To CartItem.rb model

changed attr_reader :inventory, :quantity to attr_accessor :inventory, :quantity

def getinventoryid
   @inventory.id
end

To Cart.rb model:

changed attr_reader :items to attr_accessor :items

def remove_inventory(inventory)
   @items.delete_if {|item| item.inventory == inventory }
end

To inventories_controller.rb:

def remove_cart_item
  inventory = Inventory.find(params[:id])
  @cart = find_cart
  @cart.remove_inventory(inventory)
  redirect_to_index("The item was removed")
 end
JZ