04 Feb 2013, 17:31
Generic-user-small

Stefano Cavalieri (3 posts)

Add a link next to each item in the cart. When clicked it should invoke an action to decrement the quantity of the item, deleting it from the cart when the quantity reaches zero. Get it working without using AJAX first, and then add the AJAX goodness.

AJAX PROBLEM

My _line_item.html.erb partial :

 <% if line_item == @current_item %>
<tr id="current_item">
<% else %>
<tr>
<% end %>
  <td><%= line_item.quantity %>&times;</td>
  <td><%= line_item.product.title %></td>
  <td class="item_price"><%= currency_euro(line_item.total_price) %></td>
  <td> <%= button_to '-', line_item,  :method => :delete, :remote => true  %> </td>
	
</tr> 

line_item_controller (method destroy) :

# DELETE /line_items/1
  # DELETE /line_items/1.xml
  def destroy
      @line_item = LineItem.find(params[:id])
      
      respond_to do |format|
        if @line_item.quantity > 1
          @line_item.update_attributes(:quantity => @line_item.quantity - 1)
          format.html { redirect_to(store_url) }
          format.js   {@current_item = @line_item}
          format.xml  { head :ok }
        else
          @line_item.destroy
          format.html { redirect_to(store_url) }
          format.js   
          format.xml  { head :ok }
        end
      end
  end 

destroy.js.rjs (app/views/line_items/) :

 if @cart.total_items == 0
  page[:cart].visual_effect :blind_up
else
  
  page.replace_html('cart', render(@cart))
    unless @line_item.nil?  
      page[:current_item].visual_effect :highlight,
                                    :startcolor => "#ffff00",
                                    :endcolor => "#114411"
     end
end

Ajax for destroy a line_item record doesn’t work . When i create a line_item in the cart (create.js.rjs) ajax work perfectly.

create.js.rjs :

 page.replace_html('cart', render(@cart)) 

page[:cart].visual_effect :blind_down if @cart.total_items == 1

page[:current_item].visual_effect :highlight,
                                  :startcolor => "#88ff88",
                                  :endcolor => "#114411" 

After press the button for erase line_item record, nothing happens, but if i refresh the page, the line_item’s quantity is update. So i think that destroy.js.rjs file doesn’t work good.

Terminal log when i press the button for erase a line_item record :

 Started POST "/line_items/298" for 127.0.0.1 at Mon Feb 04 18:03:24 +0100 2013
  Processing by LineItemsController#destroy as JS
  Parameters: {"id"=>"298", "_"=>"", "authenticity_token"=>"a8Pk0sS4QhQ4+xQQYrtboYrGLY91YkemYCUFNVr38H0="}
  LineItem Load (0.3ms)  SELECT "line_items".* FROM "line_items" WHERE "line_items"."id" = 298 LIMIT 1
  AREL (0.5ms)  UPDATE "line_items" SET "updated_at" = '2013-02-04 17:03:24.858678', "quantity" = 1 WHERE "line_items"."id" = 298
Rendered line_items/destroy.js.rjs (0.8ms)
Completed   in 93ms

ActionView::Template::Error (undefined method `total_items' for nil:NilClass):
    1: if @cart.total_items == 0
    2: page[:cart].visual_effect :blind_up
    3: else
    4:   
  app/views/line_items/destroy.js.rjs:1:in `_app_views_line_items_destroy_js_rjs__518012458_2262290780_0'
  app/views/line_items/destroy.js.rjs:1:in `_app_views_line_items_destroy_js_rjs__518012458_2262290780_0'

Rendered /opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.5/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.8ms)
Rendered /opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.5/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (10.4ms)
Rendered /opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.5/lib/action_dispatch/middleware/templates/rescues/template_error.erb within rescues/layout (24.1ms) 

Where I’m wrong?

Thanks so much.

06 Feb 2013, 16:23
Generic-user-small

Adam Tait (8 posts)

Can you post cart.rb; Do you have a total_items method defined in cart.rb?

06 Feb 2013, 23:00
Generic-user-small

Stefano Cavalieri (3 posts)

cart.rb :

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)
      current_item.price = current_item.product.price
    end
    current_item
  end
  
  def total_price
    line_items.to_a.sum { |item| item.total_price }
  end
  
  def total_items
    line_items.sum(:quantity)
  end
  
end

Note that the previous create.js.rjs file uses the total_items method and it works perfectly !

With this version of destroy.js.rjs file ( with first istruction 1: if @cart.total_items == 0), i get the previous error :

 ActionView::Template::Error (undefined method `total_items' for nil:NilClass): 

but trying other version of the destroy.js.rjs file (where for example the first instruction is page.replace_html(‘cart’, render(@cart)), the error become:

 ActionView::Template::Error (undefined method `model_name' for NilClass:Class):
    1: page.replace_html('cart', render(@cart))
    2: if @cart.total_items == 0
    3:   page[:cart].visual_effect :blind_up
    4: elsif @current_item.quantity? > 0
  app/views/line_items/destroy.js.rjs:1:in `_app_views_line_items_destroy_js_rjs__518012458_2262595780_0'
  app/views/line_items/destroy.js.rjs:1:in `_app_views_line_items_destroy_js_rjs__518012458_2262595780_0'

It’s strange, but in any case the destroy.js.rjs file has this error !

  You must be logged in to comment