首页 > 解决方案 > 如何防止将相同产品添加到购物车

问题描述

在我的电子商务脚本中,可以将相同的产品添加到购物车中,我该如何防止呢?

def add
    @cart.save if @cart.new_record?
    session[:cart_id] = @cart.id
    product = Product.find(params[:id])
    LineItem.create! :order => @cart, :product => product, :price => product.price
    @cart.recalculate_price!
    flash[:notice] = "Item added to cart!"
    redirect_to '/cart'
  end

标签: ruby-on-railsruby-on-rails-5

解决方案


在 Cart.product_id 上添加唯一性验证,以 Cart.id 为范围:

class Cart < ApplicationRecord
  validates :product_id, uniqueness: {scope: :id}
end

但要注意竞争条件

更新:如果没有实际Cart模型添加验证LineItem

class LineItem < ApplicationRecord
  validates :product_id, uniqueness: {scope: :order_id}
end

更新2:重构add方法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

更新 3:检查是否product存在:

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

推荐阅读