【发布时间】:2019-10-08 19:07:54
【问题描述】:
我正在实施一个优惠券/优惠券系统,用户可以为给定的产品购买一对多的优惠券。例如,用户可以在 X 零售商处购买两张折扣软饮料的优惠券。优惠券可以同时或在 2 个不同的时间点领取,即今天领取一张,明天领取下一张。
将优惠券添加到购物车时,将生成订单以及每张优惠券的关联 order_item + 数量。
成功完成结帐后,我需要将优惠券复制到quantity > 1 的位置,因为我需要为每张优惠券设置一个claim_on 时间戳以进行审核。
换句话说,我需要从以下位置更新 OrderItem:
id,quantity,order_id,product_id,claimed_on
1, 2, 001, 010, nil
2, 3, 001, 020, nil
在购物车到
id,quantity,order_id,product_id,claimed_on
1, 1, 001, 010, nil
2, 1, 001, 020, nil
3, 1, 001, 010, nil
4, 1, 001, 020, nil
5, 1, 001, 020, nil
一旦购买成功。
到目前为止,我已经找到了这个answer,但我很难从 activerecord 的角度来查看实现。我主要担心的是当多个用户使用平台时会生成任何类型的锁或损坏表。
我考虑过创建一个仅包含成功订单但似乎不是一个好习惯的第三张表。
这是我的模型:
class Order < ApplicationRecord
belongs_to :user
has_many :order_items
end
OrderItem 看起来像:
# id :bigint(8) not null, primary key
# quantity :integer default(0), not null
# created_at :datetime not null
# updated_at :datetime not null
# order_id :bigint(8)
# product_id :bigint(8)
#
# Indexes
#
# index_order_items_on_order_id (order_id)
# index_order_items_on_product_id (product_id)
#
# Foreign Keys
#
# fk_rails_... (order_id => orders.id)
# fk_rails_... (product_id => products.id)
#
class OrderItem < ApplicationRecord
belongs_to :order
belongs_to :product
validates :quantity, numericality: { greater_than_or_equal_to: 0 }
after_save :destroy_if_zero
def total
quantity * product.active_product_prices.price
end
private
def destroy_if_zero
destroy if quantity.zero?
end
end
更新:
我正在使用 Stripe 处理付款,因此 Order 模型有一个 Charge_id 来存储 Stripe 令牌 - 希望对您有所帮助。
【问题讨论】:
-
你用的是什么关系型数据库?
-
我正在使用 postgresql
-
一个相当重要的注意事项:永远不要在动态
total属性中使用当前产品价格。您应该将产品价格存储在您的 OrderItem 中,因为它不会在产品价格更新时更改。 -
公平点@BroiSatse - 感谢您的建议
标签: ruby-on-rails ruby postgresql ruby-on-rails-5