[英]Rails: “Caching” the average of an associated model's values
In Rails, I have some models that look like this: 在Rails中,我有一些看起来像这样的模型:
class Product
has_many :listings
end
class Listing
belongs_to :product
# quantity_in_kg
# total_price
# price_per_kg = total_price / quantity_in_kg
end
I'd like to be able to compare the listings for a product based on the price per kilogram, compared to the price per kilogram for the product. 我希望能够根据产品的每公斤价格与产品的每公斤价格进行比较。 For example, this listing is only $2 per kilogram, whereas the product's average is $3. 例如,此清单的价格仅为每公斤2美元,而产品的平均价格为3美元。
Eventually, I'd like to be able to run a query that says "give me all of the listings which are below the average price of their product". 最终,我希望能够运行一个查询,说“给我所有低于其产品平均价格的商品”。
What's an effective way of doing this? 有效的方法是什么? I was thinking of something custom with ActiveRecord callbacks, and caching the per-kilo average in the products
table, and the per-kilo price for each listing in the listings
table. 我正在考虑使用ActiveRecord回调进行自定义,并在products
表中缓存每千平均价格,并在listings
表中缓存每个列表的每千价格。 There's probably a lot of scope for getting that wrong, so I was wondering if there was another way. 可能有很多问题可以解决,所以我想知道是否还有另一种方法。
I'm using Postgres 9.6 and Rails 5.1.0. 我正在使用Postgres 9.6和Rails 5.1.0。
(Bonus points: listings can also be active/inactive, and I'd only like to compare the average of all active listings). (加分点:列表也可以是活跃/不活跃的,我只想比较所有活跃列表的平均值)。
My suggestion is to start with a simple after_save
callback and see where it takes you. 我的建议是从一个简单的after_save
回调开始,看看它将带您到哪里。 You can add some updating criteria like "only recalculate on create/destroy or if active
has been updated", add some transactions if you're feeling extra careful, etc.. 您可以添加一些更新条件,例如“仅在创建/销毁时重新计算,或者如果active
已被更新”,如果您格外小心,则添加一些事务等。
If gets too slow, add a background worker to update it regularly (for example). 如果太慢,请添加后台工作人员定期进行更新(例如)。
class Listing
after_save do
product.update(
avg_price_per_kg: product.listings.where(active: true).average(:price_per_kg)
)
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.