Rails_learner Rails_learner - 5 months ago 52
Ruby Question

Rails Issue with User Cart

I've got a Rails cart for a customer which works but only on the second attempt of trying to 'add-to-cart'.

So every time I click 'add to cart', the cart is empty the first time. But on second attempt, the item is added to cart.

What am I doing wrong?

Here's the customer controller code:

class Customer::CartsController < ApplicationController
before_action :authenticate_user!
def show
@cart = if current_user
current_user.cart ||= Cart.find_by(session[:cart_id])
session[:cart_id] = nil if current_user.cart.purchased_at
end
if session[:cart_id].nil?
current_user.cart = Cart.create!(user_id: params[:id])
session[:cart_id] = current_user.cart.id
end
@cart = current_user.cart
end
end


Regular Carts controller

class CartsController < ApplicationController
skip_before_action :authorize, only: [:create, :update, :destroy]
before_action :set_cart, only: [:show, :edit, :update, :destroy]
rescue_from ActiveRecord::RecordNotFound, with: :invalid_cart

def index
@carts = Cart.all
end

def show
end

def new
@cart = Cart.new
end

def edit
end

def create
@cart = Cart.new(cart_params)

respond_to do |format|
if @cart.save
format.html { redirect_to @cart, notice: 'Cart was successfully created.'}
format.json { render :show, status: :created, location: @cart }
else
format.html { render :new }
format.json { render json: @cart.errors, status: :unprocessable_entity }
end
end
end

def update
respond_to do |format|
if @cart.update(cart_params)
format.html { redirect_to @cart, notice: 'Cart was successfully updated.' }
format.json { render :show, status: :ok, location: @cart }
else
format.html { render :edit }
format.json { render json: @cart.errors, status: :unprocessable_entity }
end
end
end

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

private
# Use callbacks to share common setup or constraints between actions.
def set_cart
@cart = Cart.find(params[:id])
end

# Never trust parameters from the scary internet, only allow the white list through.
def cart_params
params[:cart]
end

def invalid_cart
logger.error "Attempt to access invalid cart #{params[:id]}"
redirect_to root_path, notice: 'Invalid cart'
end
end


Line Items controller create method

def create
product = Product.find(params[:product_id])
@line_item = @cart.add_product(product.id, params[:size])

respond_to do |format|
if @line_item.save
format.html { redirect_to customer_cart_path }
format.json { render :show, status: :created, location: @line_item }
else
format.html { render :new }
format.json { render json: @line_item.errors, status: :unprocessable_entity }
end
end
end


Any help would be appreciated. Thanks in advance!

Answer

Previously working on cart i had the same issue as far as i remember it came from current_cart method sitting in your application controller

I ended up changing it to this

def current_cart
    @cart = Cart.find(session[:cart_id]) 
    rescue ActiveRecord::RecordNotFound
    @cart = Cart.create
    session[:cart_id] = @cart.id 
    @cart
end

also prior to @cart.add_.... I have the call for the method in my lineitems controller create method

@cart = current_cart

Edit 1

this is my lineitems create method I think you are missing a creation of cart if there is none

@lineitem = Lineitem.new(lineitem_params)
@cart = current_cart
item = Item.find(lineitem_params[:item_id])
@lineitem = @cart.addItem(item.id,@lineitem.quantity)