Add uniqueness validation on Cart.product_id, scoping by Cart.id:
class Cart < ApplicationRecord
validates :product_id, uniqueness: {scope: :id}
end
But beware of race conditions.
UPDATE: If no actual Cart
model add validation to LineItem
:
class LineItem < ApplicationRecord
validates :product_id, uniqueness: {scope: :order_id}
end
UPDATE 2: refactor add
method with find_or_initialize_by
:
def add
@cart.save if @cart.new_record?
session[:cart_id] = @cart.id
product = Product.find(params[:id])
line_item = LineItem.find_or_initialize_by(order: @cart,
product: product)
line_item.price = product.price
line_item.save!
@cart.recalculate_price!
flash[:notice] = "Item added to cart!"
redirect_to '/cart'
end
UPDATE 3: Checking for product
existence:
def add
@cart.save if @cart.new_record?
session[:cart_id] = @cart.id
product = Product.find(params[:id])
line_item = LineItem.find_by(order: @cart, product: product)
if line_item
notice = "ERROR: Product already in the cart"
else
LineItem.create!(order: @cart,
product: product,
price: product.price)
@cart.recalculate_price!
notice = "Item added to cart!"
end
flash[:notice] = notice
redirect_to '/cart'
end
8
solved How do I prevent the addition of the same product to the cart [closed]