我有三种型号进货,产品和尺寸
#Product
has_many :sizes, as: :sizeable
#Size
belongs_to :sizeable, polymorphic: true
restocking.rb
class Restocking < ApplicationRecord
has_many :sizes, as: :sizeable
belongs_to :product
accepts_nested_attributes_for :sizes
def update_existing_product
product = self.product
product.update_attributes(
price: self.price,
buying_price: self.buying_price,
)
sizes = Size.where(sizeable_id: self.product_id)
self.sizes.each do |restocking_size|
sizes.each do |product_size|
if product_size.size_name == restocking_size.size_name
product_size.quantity += restocking_size.quantity
product_size.save
end
end
end
end
end
因此update_existing_product
方法会更新现有尺寸的价格和数量...
如果找到类似的size_name
,则会更新现有的尺寸数量,否则会创建一个新的尺寸...
我无法正确创建新尺寸...
我应该使用这种Size.create
方法,但是当我将其放在循环中时,它会多次创建相同的大小。
Size.create!(
sizeable_id: self.product_id,
sizeable_type: "Product",
size_name: restocking_size.size_name,
quantity: restocking_size.quantity,
)
答案 0 :(得分:1)
Size
被多次创建。
修正代码如下:
self.sizes.each do |restocking_size|
if (existing_size = sizes.find{|s| s.size_name == restocking_size.size_name })
existing_size.tap{|s| s.quantity += restocking_size.quantity }.save!
else
# no existing, here goes create
end
end
但是请记住,如果此代码恰好在其他一些代码更新相同数据的同时运行,则在应用程序级别处理此问题可能会导致争用情况。 例如:
sizes
,quantity
中有10个quantity
是15,而一件商品已售出可以通过在每个更新计数器的地方使用record#with_lock{ here update happens }
来避免(但是这会重新加载记录,对于大容量而言可能效率不高)。