如何防止将同一产品添加到购物车

时间:2019-04-24 12:42:18

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

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

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

1 个答案:

答案 0 :(得分:3)

在Cart.product_id上添加uniqueness验证,并根据Cart.id进行范围界定:

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

但要注意race conditions

更新:如果没有实际的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