Rails Cart Returns the number of items on Destroy

I am new to rails and have a simple grocery store website. When a user adds a product to their cart or updates the number of rows in the cart, they add / remove from the base quantity of the product as needed. However, when they empty their cart (delete / destroy the cart), it does not restore the amount of the base product, as if they were not buying anything. How do I update the destroy method to return the rows listed below to the original product quantity?

line_items_controller.rb - An example of a method to completely remove one line_item product in the cart and increase the amount of the base product:

def empty
  product = Product.find(params[:product_id])
  @line_item = @cart.empty_product(product)
  @total = @line_item.quantity
  product.increment!(:quantity, @total)

  respond_to do |format|
    if @line_item.save
      format.html { redirect_to :back, notice: 'Product removed.' }
      format.js
      format.json { render :show, status: :ok, location: @line_item }
    else
      format.html { render :edit }
      format.json { render json: @line_item.errors, status: :unprocessable_entity }
    end
  end
end

      

carts / show.html.erb - Call to destroy / empty the cart:

<%= link_to 'Empty Cart', @cart, method: :delete, data: {confirm: 'Are you sure you want to empty your cart?'}, :class => 'btn btn-danger whiteText' %>

      

carts_controller.rb - Current carts destruction method:

def destroy
  @cart.destroy if @cart.id == session[:cart_id]
  session[:cart_id] = nil
  respond_to do |format|
    format.html { redirect_to root_path, notice: 'Cart was emptied.' }
    format.json { head :no_content }
  end
end

      

carts_controller.rb - What I'm trying to do (I think there might be a problem with this as it doesn't know how to resolve product = Product.find (params [: product_id])):

def destroy
  @cart.destroy if @cart.id == session[:cart_id]
    @cart.line_items.each do
      product = Product.find(params[:product_id])
      @total = @line_item.quantity
      product.increment!(:quantity, @total)
    end
  session[:cart_id] = nil
  respond_to do |format|
    format.html { redirect_to root_path, notice: 'Cart was emptied.' }
    format.json { head :no_content }
  end
end

      

EDIT

Tried changing the destroy method:

def destroy
  if @cart.id == session[:cart_id]
    @cart.line_items.each do |l|
      product = Product.where(:id => l.product_id)
      @total = @l.quantity
      product.increment!(:quantity, @total)
    end
    @cart.destroy
  end
  session[:cart_id] = nil
  respond_to do |format|
    format.html { redirect_to root_path, notice: 'Cart was emptied.' }
    format.json { head :no_content }
  end
end

      

This gives me the following error, although I was able to use an increment! by product quantity in line_control_name:

undefined method `increment!' for #<Product::ActiveRecord_Relation:0xb5ad1b4>

      

Also tried calling the path directly into the carts controller method. It shows the cart is empty successfully, but does not return the product quantity depending on how it looks when I call this same method in html:

if @cart.id == session[:cart_id]
  @cart.line_items.each do |l|
    empty_line_item_path(product_id: l.product)
  end
  @cart.destroy
end

      

+3


source to share


2 answers


For the destruction question, you can actually do it at the model level.

In your LineItem model, you can do ...

before_destroy { |record| record.product.increment!(:quantity, record.quantity }

      



This assumes the LineItem has ...

belongs_to :product

      

And will ensure the product quantity is updated regardless of where the line_item entry was destroyed.

+3


source


For your error after your EDIT part, you have ...

  product = Product.where(:id => l.product_id)
  @total = @l.quantity
  product.increment!(:quantity, @total)

      

The method where

does not return a single product, it returns a production relation (which probably only contains one product).



It would be better ...

  product = Product.find_by(:id => l.product_id)
  @total = @l.quantity
  product.increment!(:quantity, @total)

      

... which will return a product object.

+2


source







All Articles