In Rails, I have some models that look like this:
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.
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. 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.
(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. 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..
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.