我在向购物车添加商品时遇到问题,而不是更新商品(如果已存在),则会创建重复商品。我知道我需要通过验证来检查order_item是否存在,但我不确定如何或在何处进行。
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
helper_method :current_order
helper_method :current_buylist_order
def current_order
if !session[:order_id].nil?
Order.find(session[:order_id])
else
Order.new
end
end
end
class OrderItemsController < ApplicationController
def create
@order = current_order
@order_item = @order.order_items.new(order_item_params)
@order.save
session[:order_id] = @order.id
end
def update
@order = current_order
@order_item = @order.order_items.find(params[:id])
@order_item.update_attributes(order_item_params)
@order_items = @order.order_items
end
def destroy
@order = current_order
@order_item = @order.order_items.find(params[:id])
@order_item.destroy
@order_items = @order.order_items
end
private
def order_item_params
params.require(:order_item).permit(:quantity, :card_id)
end
end
class CartsController < ApplicationController
def show
@order_items = current_order.order_items
end
end
class Order < ActiveRecord::Base
belongs_to :order_status
has_many :order_items
before_create :set_order_status
before_save :update_subtotal
def subtotal
order_items.collect { |oi| oi.valid? ? (oi.quantity * oi.unit_price) : 0 }.sum
end
private
def set_order_status
self.order_status_id = 1
end
def update_subtotal
self[:subtotal] = subtotal
end
end
class OrderItem < ActiveRecord::Base
belongs_to :card
belongs_to :order
validates :quantity, presence: true, numericality: { only_integer: true, greater_than: 0 }
validate :card_present
validate :order_present
before_save :finalize
def unit_price
if persisted?
self[:unit_price]
else
card.price
end
end
def total_price
unit_price * quantity
end
private
def card_present
if card.nil?
errors.add(:card, "is not valid or is not active.")
end
end
def order_present
if order.nil?
errors.add(:order, "is not a valid order.")
end
end
def finalize
self[:unit_price] = unit_price
self[:total_price] = quantity * self[:unit_price]
end
end
答案 0 :(得分:0)
在您OrderItemsController
中,在create
和update
方法中,您使用行@order_item = @order.order_items.new(order_item_params)
,每次调用其中一个方法时,都会初始化新项。您需要更改这些方法,因此只有当具有相同参数的项目尚不存在时,它们才会创建新项目。请查看first_or_initialize
或first_or_create
方法。或者使用一个简单的条件(例如,如果订单中的商品增加数量为1,则创建新商品)
答案 1 :(得分:0)
在订单项控制器中的create方法下,有一个代码检查现有产品,然后如果您多次添加到购物车中,则增加数量。您也可以使用jQuery禁用按钮。
在order_items_controller中的create方法下
require "active_record/connection_adapters/postgresql_adapter"
module ActiveRecord
module ConnectionAdapters
class PostgreSQLAdapter
NATIVE_DATABASE_TYPES.merge!(
timestamp: { name: "timestamptz" }
)
end
end
end
添加和更新数量的额外方法
@product_id = params['order_item']['product_id']
@order.order_items.each do |oi|
if oi.product_id.to_s == @product_id
updater(oi.id,params['order_item']['quantity']) and return
end
end
答案 2 :(得分:0)
对我有用的是:
def create
@order = current_order
if OrderItem.where("card_id = ? AND order_id = ?",
params[:order_item][:card_id], @order.id.to_s).empty?
@order_item = OrderItem.new(order_item_params)
@order_item.order = current_order
@order_item.save
else
@order_item = OrderItem.where("card_id = ? AND order_id = ?",
params[:order_item][:card_id], @order.id.to_s).first
quantity = @order_item.quantity += params[:order_item][:quantity].to_i
@order_item.update(quantity: quantity)
end
end