[LRUG] N+1
Andrew Stewart
boss at airbladesoftware.com
Tue Aug 4 04:13:20 PDT 2020
Hello LRUG!
I am having trouble getting rid of database calls to read intermediate objects in a hierarchy.
I have some models like this:
class Alpha < ApplicationRecord
has_many :betas
end
class Beta < ApplicationRecord
belongs_to :alpha
has_many :gammas
has_many :deltas, through: :gammas
end
class Gamma < ApplicationRecord
belongs_to :beta
has_many :deltas
end
class Delta < ApplicationRecord
belongs_to :gamma
end
And a controller action like this:
alpha = Alpha.first
@betas = alpha.betas
.joins(gammas: :deltas) # exclude betas without deltas
.includes(gammas: :deltas)
.distinct
.alphabetical
And a view (pseudocode):
- @betas.each do |beta| # loads the @betas relation once as expected
= beta.name
- beta.deltas.each do |delta| # [A] SQL query to get the beta's deltas (once per beta)
= delta.name
= delta.gamma.name # [B] SQL query to get the delta's gamma (once per delta)
It seems to me I should be able to avoid the nested queries, [A] and [B], because the @betas relation includes the gammas and deltas, but I haven't succeeded yet.
Alternatively, in the console:
beta = Beta.first
beta.deltas.first.gamma.name # expected 1 query; actually 2
I'm using Rails 6.0.3.1 and Ruby 2.7.
Any pointers would be much appreciated!
Many thanks,
Andy Stewart
More information about the Chat
mailing list