创建了空记录,该如何解决?

时间:2019-01-20 21:48:59

标签: ruby-on-rails

我希望在我的网上商店中,用户可以不用帐户就可以开始购物,他可以选择商品并将其添加到购物车中。 如果他还没有任何帐户,他会在付款过程之前创建自己的帐户。

我也希望该订单属于用户

在我的 order.rb 中添加

belongs_to :user, optional: true

因此,我可以创建订单而无需 user_id 。 我在付款创建方法中使用 user_id 更新了订单。 我需要这种关联,因为我想检索用户的订单。

在我的 application_controller.rb 中,我有一种设置购物车的方法

before_action :current_cart

def current_cart
    @current_cart ||= ShoppingCart.new(token: cart_token)
end
helper_method :current_cart

private

     def cart_token
       return @cart_token unless @cart_token.nil?
       session[:cart_token] ||= SecureRandom.hex(8)
       @cart_token = session[:cart_token]
     end

我的用户付款后,就会记录他的订单。 我还发现,由于我不强制与用户和订单建立关联,因此由于application_controller中的current_cart而创建了空订单...

这是 shopping_cart.rb 模型

class ShoppingCart

  delegate :sub_total, to: :order

  def initialize(token:)
    @token = token
  end

  def order
    @order ||= Order.find_or_create_by(token: @token, status: 0) do |order|
      order.sub_total = 0
    end
  end

  def items_count
    order.items.sum(:quantity)
  end

  def add_item(product_id:, quantity:1 , size_id:) 
    @product = Product.find(product_id)
    @size = Size.find_by(id: size_id)

    @order_item =  if order.items.where(product_id: product_id).where(size_id: size_id).any?
       order.items.find_by(product_id: product_id, size_id: size_id)
    else
     order.items.new(product_id: product_id, size_id: size_id)
    end

    @order_item.price = @product.price_cents
    @order_item.quantity = quantity.to_i

    ActiveRecord::Base.transaction do
      @order_item.save
      update_sub_total!
    end
    CartCleanupJob.set(wait: 1.minutes).perform_later(order.id)
  end

  def change_qty(id:, quantity:1, product_id:, size_id:)
    @size = Size.find_by(id: size_id)
    @order_item = order.items.find_by(product_id: product_id, size_id: size_id)
    @order_item.quantity = quantity.to_i
    @order_item.save
    update_sub_total!
  end

  def remove_item(id:)
    ActiveRecord::Base.transaction do
      order.items.destroy(id)
      update_sub_total!
    end
  end

  private

  def update_sub_total!
    order.sub_total = order.items.sum('quantity * price')
    order.save
  end


end

我应该怎么做才能使我的用户可以在付款前创建自己的帐户,而不创建空订单...?

1 个答案:

答案 0 :(得分:2)

在ShoppingCart类的order方法中,使用find_or_create_by,顾名思义,调用Order类的create方法。如果您切换到find_or_initialize_by,则将调用new方法,该方法将为您提供Order对象,但不会在数据库中创建。

  def order
    @order ||= Order.find_or_initialize_by(token: @token, status: 0) do |order|
      order.sub_total = 0
    end
  end