ruby-on-rails - 创建了一个空记录,我该如何解决这个问题?
问题描述
在我的在线商店中,我希望用户可以在没有帐户的情况下开始购物,他可以选择商品并将它们添加到他的购物车中。如果他还没有任何帐户,他会在付款过程之前创建他的帐户。
我也想要那个订单 belongs_to 用户
在我的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
我应该怎么做才能让我的用户在付款前创建他的帐户,而不是创建一个空订单......?
解决方案
find_or_create_by
在您的 ShoppingCart 类的 order 方法中,顾名思义,您使用它调用create
Order 类的方法。如果您切换到 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
推荐阅读
- php - codeigniter:试图从图像名称中删除“&”符号,但没有发生,该 getimagesize() 的 bcoz 给出错误
- angular - 每次单击按钮时添加新按钮,并在角度 6 中添加新颜色的按钮
- reactjs - 如何解决提供给`ForwardRef(TextField)`的警告值`inherit`的无效道具`color`,预期为[“primary”,“secondary”]之一
- javascript - 如何在选定的 Jquery 中实现水平滚动条以下拉?
- laravel - 在 Google App Engine (Laravel 6.2) 上设置多个 Cloud SQL 连接
- c# - 模块化 C# WinForms 应用程序中的跨线程通信
- sql - 插入当前日期和时间
- sed - sed:删除匹配行和之后的所有内容
- sql-server - 较新 SQL 版本中的旧数据库兼容性
- sql - LINQ 为空字符串生成错误的 SQL