保存前计算嵌套项目
Count nested item before save
让订单和项目模型。
class Order < ApplicationRecord
has_many :items, inverse_of: :order, dependent: :delete_all
before_save do
self.packed_volume = compute_packed_volume
end
private
def compute_packed_volume
items.count * 0.1O
end
end
和
class Item < ApplicationRecord
belongs_to :order, inverse_of: :items
end
问题是 items.count 等于 0,因为尚未创建项目。
我们如何在创建订单时获取将要创建的项目数以使用它?
您要找的是 "counter cache"。它实现了你正在尝试做的事情。 ActiveRecord 可以为您做到这一点:
belongs_to :post, :counter_cache => true
有几个 gem 执行此操作,每当创建或删除 child 记录时更新 parent 记录中的计数字段。
Gem counter-cache
很简单。另一个,counter-culture
更进一步,包括支持在 has_many :through
关系中计算 children。
你的例子有点有趣,因为你不是在寻找计数,而是在计算计数。因此,您可以使用它并使用它来动态计算 packed_volume,可能在模型上的方法与您的 compute_packed_volume()
方法非常相似。
如果您想在 parent 记录中存储实际交易量(也许计算起来非常昂贵),您需要从将回调放在 parent 模型上转变为将它们放在child 模型。 counter_culture
gem 支持 "Delta Magnitude"。像这样:
class Item < ActiveRecord::Base
belongs_to :order
counter_culture :order, column_name: :packed_volume, delta_magnitude: 0.1
end
class Order < ActiveRecord::Base
has_many :items
end
delta_magnitude
参数可以带proc,所以可以做更复杂的事情。也许是这样的:
counter_culture :order, column_name: :packed_volume, delta_magnitude: -> {|item| item.length * item.width * item.height }
如果您有其他要求无法使用 gem,您可以按照这些思路推出自己的解决方案。您需要为 after_create
和 before_destroy
添加回调到 increment/decrement parent 记录。如果您的交易量计算变得更加复杂,您可能还需要在记录更改时更新订单。
尝试 size
,它不会 运行 查询
items.size * 0.1O
希望对您有所帮助!
让订单和项目模型。
class Order < ApplicationRecord
has_many :items, inverse_of: :order, dependent: :delete_all
before_save do
self.packed_volume = compute_packed_volume
end
private
def compute_packed_volume
items.count * 0.1O
end
end
和
class Item < ApplicationRecord
belongs_to :order, inverse_of: :items
end
问题是 items.count 等于 0,因为尚未创建项目。 我们如何在创建订单时获取将要创建的项目数以使用它?
您要找的是 "counter cache"。它实现了你正在尝试做的事情。 ActiveRecord 可以为您做到这一点:
belongs_to :post, :counter_cache => true
有几个 gem 执行此操作,每当创建或删除 child 记录时更新 parent 记录中的计数字段。
Gem counter-cache
很简单。另一个,counter-culture
更进一步,包括支持在 has_many :through
关系中计算 children。
你的例子有点有趣,因为你不是在寻找计数,而是在计算计数。因此,您可以使用它并使用它来动态计算 packed_volume,可能在模型上的方法与您的 compute_packed_volume()
方法非常相似。
如果您想在 parent 记录中存储实际交易量(也许计算起来非常昂贵),您需要从将回调放在 parent 模型上转变为将它们放在child 模型。 counter_culture
gem 支持 "Delta Magnitude"。像这样:
class Item < ActiveRecord::Base
belongs_to :order
counter_culture :order, column_name: :packed_volume, delta_magnitude: 0.1
end
class Order < ActiveRecord::Base
has_many :items
end
delta_magnitude
参数可以带proc,所以可以做更复杂的事情。也许是这样的:
counter_culture :order, column_name: :packed_volume, delta_magnitude: -> {|item| item.length * item.width * item.height }
如果您有其他要求无法使用 gem,您可以按照这些思路推出自己的解决方案。您需要为 after_create
和 before_destroy
添加回调到 increment/decrement parent 记录。如果您的交易量计算变得更加复杂,您可能还需要在记录更改时更新订单。
尝试 size
,它不会 运行 查询
items.size * 0.1O
希望对您有所帮助!