<div dir="ltr">Hey Andy,<div><br></div><div>I think the problem might be that eager loading is applied to specific associations, and the ones you're applying eager loading to aren't the ones that you're using to perform your reads.</div><div><br></div><div>Specifically, with `some_beta_scope.includes(gammas: :deltas)` you're eager loading the `Beta#gammas` and `Gamma#deltas` associations, but in your view you're using `Beta#deltas` and `Delta#gamma` to actually load the data. (<a href="http://screenshots.urbanautomaton.com/20200804-p79pj.png">possibly-unhelpful illustration</a>)</div><div><br></div><div>You'd either need to rewrite the eager load to match your access pattern (`some_beta_scope.includes(deltas: :gamma)`, I <i>think</i>), or rewrite the loop to match the eager loading, e.g.</div><div><br></div><div>- @betas.each do |beta|<br> = <a href="http://beta.name/" rel="noreferrer" target="_blank">beta.name</a><br> - beta.gammas.each do |gamma|</div><div> - gamma.deltas.each do |delta|<br> = <a href="http://delta.name/" rel="noreferrer" target="_blank">delta.name</a><br> = <a href="http://delta.gamma.name/" rel="noreferrer" target="_blank">gamma.name</a><br></div><div><br></div><div>Does that work?</div><div><br></div><div>Cheers,</div><div>Simon</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, 4 Aug 2020 at 12:14, Andrew Stewart <<a href="mailto:boss@airbladesoftware.com">boss@airbladesoftware.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello LRUG!<br>
<br>
I am having trouble getting rid of database calls to read intermediate objects in a hierarchy.<br>
<br>
I have some models like this:<br>
<br>
class Alpha < ApplicationRecord<br>
has_many :betas<br>
end<br>
<br>
class Beta < ApplicationRecord<br>
belongs_to :alpha<br>
has_many :gammas<br>
has_many :deltas, through: :gammas<br>
end<br>
<br>
class Gamma < ApplicationRecord<br>
belongs_to :beta<br>
has_many :deltas<br>
end<br>
<br>
class Delta < ApplicationRecord<br>
belongs_to :gamma<br>
end<br>
<br>
And a controller action like this:<br>
<br>
alpha = Alpha.first<br>
@betas = alpha.betas<br>
.joins(gammas: :deltas) # exclude betas without deltas<br>
.includes(gammas: :deltas)<br>
.distinct<br>
.alphabetical<br>
<br>
And a view (pseudocode):<br>
<br>
- @betas.each do |beta| # loads the @betas relation once as expected<br>
= <a href="http://beta.name" rel="noreferrer" target="_blank">beta.name</a><br>
- beta.deltas.each do |delta| # [A] SQL query to get the beta's deltas (once per beta)<br>
= <a href="http://delta.name" rel="noreferrer" target="_blank">delta.name</a><br>
= <a href="http://delta.gamma.name" rel="noreferrer" target="_blank">delta.gamma.name</a> # [B] SQL query to get the delta's gamma (once per delta)<br>
<br>
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.<br>
<br>
Alternatively, in the console:<br>
<br>
beta = Beta.first<br>
<a href="http://beta.deltas.first.gamma.name" rel="noreferrer" target="_blank">beta.deltas.first.gamma.name</a> # expected 1 query; actually 2<br>
<br>
I'm using Rails 6.0.3.1 and Ruby 2.7.<br>
<br>
Any pointers would be much appreciated!<br>
<br>
Many thanks,<br>
<br>
Andy Stewart<br>
<br>
_______________________________________________<br>
Chat mailing list<br>
<a href="mailto:Chat@lists.lrug.org" target="_blank">Chat@lists.lrug.org</a><br>
Archives: <a href="http://lists.lrug.org/pipermail/chat-lrug.org" rel="noreferrer" target="_blank">http://lists.lrug.org/pipermail/chat-lrug.org</a><br>
Manage your subscription: <a href="http://lists.lrug.org/options.cgi/chat-lrug.org" rel="noreferrer" target="_blank">http://lists.lrug.org/options.cgi/chat-lrug.org</a><br>
List info: <a href="http://lists.lrug.org/listinfo.cgi/chat-lrug.org" rel="noreferrer" target="_blank">http://lists.lrug.org/listinfo.cgi/chat-lrug.org</a><br>
</blockquote></div>