1

I am building an app with a cart. However, I am having trouble removing items from the cart. There are resources for Items, Line_items, and Carts. They have this relationship:

class Cart < ActiveRecord::Base
has_many :line_items
has_one :order
end

class LineItem < ActiveRecord::Base
belongs_to :cart
belongs_to :item
end

I am able to add items to a cart like this:

<% for item in @items %>
      <%= link_to "Add to Cart", line_items_path(:item_id => item), :method => :post, class: "btn" %>
 <% end %>

This calls the create method in the line_items controller:

def create
@item = Item.find(params[:item_id])
@line_item = LineItem.create!(:cart => current_cart, :item => @item, :quantity => 1)
flash[:notice] = "Added #{@item.name} to sample."
redirect_to root_path
end

Here is the point of the question: I cannot figure out how to remove things from the cart. I can delete the line_item in the console by running this:

cart = Cart.last
cart.line_items.destroy(9)

How do I implement this in the app? What controller does this method go in? I am struggling to get this to work:

<% for line_item in @cart.line_items %>
       <%= link_to 'Remove', line_item, method: :delete %>
<% end %>

I have tried defining this in both the carts_controller and the line_items_controller but to no avail. My basic question is: how do you translate something from console to the app files?

Here are the routes:

 line_items GET    /line_items(.:format)           line_items#index
                          POST   /line_items(.:format)           line_items#create
            new_line_item GET    /line_items/new(.:format)       line_items#new
           edit_line_item GET    /line_items/:id/edit(.:format)  line_items#edit
                line_item GET    /line_items/:id(.:format)       line_items#show
                          PATCH  /line_items/:id(.:format)       line_items#update
                          PUT    /line_items/:id(.:format)       line_items#update
                          DELETE /line_items/:id(.:format)       line_items#destroy
                    items GET    /items(.:format)                items#index
                          POST   /items(.:format)                items#create
                 new_item GET    /items/new(.:format)            items#new
                edit_item GET    /items/:id/edit(.:format)       items#edit
                     item GET    /items/:id(.:format)            items#show
                          PATCH  /items/:id(.:format)            items#update
                          PUT    /items/:id(.:format)            items#update
                          DELETE /items/:id(.:format)            items#destroy
                   orders GET    /orders(.:format)               orders#index
                          POST   /orders(.:format)               orders#create
                new_order GET    /orders/new(.:format)           orders#new
               edit_order GET    /orders/:id/edit(.:format)      orders#edit
                    order GET    /orders/:id(.:format)           orders#show
                          PATCH  /orders/:id(.:format)           orders#update
                          PUT    /orders/:id(.:format)           orders#update
                          DELETE /orders/:id(.:format)           orders#destroy
                     root GET    /                               items#index
                   thanks GET    /thanks(.:format)               pages#thanks
                          DELETE /carts/:id(.:format)            cart#remove_item
                    carts GET    /carts(.:format)                carts#index
                          POST   /carts(.:format)                carts#create
                 new_cart GET    /carts/new(.:format)            carts#new
                edit_cart GET    /carts/:id/edit(.:format)       carts#edit
                     cart GET    /carts/:id(.:format)            carts#show
                          PATCH  /carts/:id(.:format)            carts#update
                          PUT    /carts/:id(.:format)            carts#update
  • Your general question is very broad, but you can find a solution to your delete issue [here](http://stackoverflow.com/questions/4606860/rails-3-link-to-to-destroy-not-working). – Joe Kennedy Jun 17 '14 at 23:00

2 Answers2

1

Destroy

The direct answer to your question is to put it into the destroy action of your line_items controller:

<% for line_item in @cart.line_items %>
       <%= link_to 'Remove', line_item, method: :delete %> #-> will take you to  destroy path
<% end %>

This will take you to:

#app/controllers/line_items_controller.rb
Class LineItemsController < ApplicationController
   def destroy
      @line_item = LineItem.find params[:id]
      @line_item.destroy
   end
end

--

Collection

A more robust way to handle your issue is to remove the record from the collection. This takes a little more effort, but is totally worth it:

#config/routes.rb
resources :cart, except: :destroy do
    collection do
       delete ":id", to: "cart#remove_item" #-> DELETE domain.com/cart/56
    end
end

#app/controllers/cart_controller.rb
class CartController < ApplicationController
   def remove_item
      current_cart.line_items.delete params[:id]
   end
end
Richard Peck
  • 76,116
  • 9
  • 93
  • 147
  • Thanks! For the Collection method, do I alter the button? As is, it renders a routing error: No route matches [DELETE] "/line_items" – user3750396 Jun 18 '14 at 14:41
  • Sorry, yes you'll need to use the path for the `cart`, rather than `line items` - if you print your `rake routes`, I'll be able to let you know which one you need – Richard Peck Jun 18 '14 at 15:50
  • I added the routes to the post. changing line_item to cart in the button, I get undefined local variable or method `cart' – user3750396 Jun 19 '14 at 15:47
0

You'd have a destroy method in the line_items controller. The url will be as you have coded...

<%= link_to 'Remove', line_item, method: :delete %>

I recommend button_to's for this and the 'Add to cart' if you want them to look like buttons.

Clicking that should call the correct controller and action.

class LineItemsController < ApplicationController

  def destroy
    @line_item = LineItem.find(params[:id])
    @line_item.destroy
    # Then redirect to the index or render the js view
  end

end
Mark Swardstrom
  • 17,217
  • 6
  • 62
  • 70