views:

44

answers:

1

Hi guys I was wondering if anyone could help me out, I need to clean up this controller as the resulting code to simply update an items quantity if it already exists seems way too complex.

class LineItemsController < ApplicationController  
  def create
   @product = Product.find(params[:product_id])
    if LineItem.exists?(:cart_id => current_cart.id)
      item = LineItem.find(:first, :conditions => [ "cart_id = #{@current_cart.id}"])
      LineItem.update(item.id, :quantity => item.quantity + 1)
    else  
     @line_item = LineItem.create!(:cart => current_cart, :product => @product, :quantity => 1, :unit_price => @product.price)
     flash[:notice] = "Added #{@product.name} to cart."
  end
  redirect_to root_url
 end  
end

`

As always any help is much appreciated, the code should be fairly self explanatory, thanks :)

PS posted it here as well as it looks a bit funny on here http://pastie.org/994059

+1  A: 

I think what you are looking for is:

class LineItemsController < ApplicationController
  def create
    @product = Product.find(params[:product_id])
    item = LineItem.find_or_initialize_by_cart_id(:cart_id => current_cart.id, :cart => current_cart, :product => @product, :quantity => 0, :unit_price => @product.price)
    item.increment! :quantity
    flash[:notice] = "Added #{@product.name} to cart."
    redirect_to root_url
  end
end

So what that does is call LineItem.find_by_cart_id(current_cart.id) and if it doesn't exist it creates it with the attributes passed. The one issue I don't think you can get around is updating of the quantity after making a database call (either finding -OR- creating) since you have to figure out if the resource was just created or it already existed.

DJTripleThreat
I would use some more atomic way to increase the counter: item.increment! :quantity. Your other problem is easily solved by find_or_initialize_by. You can ask item.new_record? if you are interested.
hurikhan77
@hurikhan77: great idea! I'm still relatively new to rails as well so I didn't know about `increment` or `find_or_initialize_by_`
DJTripleThreat
Thanks for all the useful comments and suggestions :)
Karl Entwistle
You can further strip this down, by initializing with count=0 and do "item.increment! :quantity" regardless of new record or not. The bang-version of increment will also save your record - so you can kill that line.
hurikhan77