I have the following models:
defined with the following relationships:
The idea is to fetch all abilities matching some criteria and for each, fetch its pricing rule. However a custom pricing rule for a particular ability can be defined on a per user basis.
Currently I fetch all matching abilities and iterate on them to either:
I am using Rails and ActiveRecord and here what I have so far:
user = User.first
Ability.all.map do |a|
user.pricing_rules.matching_ability(a).first || a.pricing_rule
end
Per user pricing rule customization should be done on demand by the business. The common workflow is to get the pricing rule from the abilities.
Any ideas or help to get me on the right track would be much appreciated.
EDIT:
Where the matching_ability
implementation is as follow:
def self.matching_ability(ability)
where(name: ability.name)
end
You can "eager load" to avoid N+1 queries like so:
user = User.includes(pricing_rules: :abilities).first
Ability.includes(:pricing_rule).map do |a|
user.pricing_rules.matching_ability(a).first || a.pricing_rule
end
You should see in the SQL generated that this adds a LEFT OUTER JOIN
to your queries, so ActiveRecord is loading the associated records in just the two queries. In particular, the user will be loaded with its pricing_rules
and the abilities
on each pricing_rule
, and the abilities will be loaded with their pricing_rules
.
However, implementing matching_ability
using where
may generate additional queries, returning you to the N+1 problem. To take advantage of the "eager load" in the first query, you may need to refactor to:
self.matching_ability(ability)
select{|a| a.name == ability.name}
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.