New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Eager loading doesn't respect prior #includes call #26586
Comments
It happens in Rails 5 too. But I feel this is a correct flow. We don't get any clue about the outer |
For the same reason that you'd wrap something in a For the In general, it seems to be restrict code re-use in a complex application. High-level methods doing eager loading need to ensure that no lower-level methods ever repeat the same eager loading on the same relation object. And low-level methods adding eager loading to a passed relation object need to ensure that nowhere up the chain also added the same eager loading. Considering how |
This issue has been automatically marked as stale because it has not been commented on for at least three months. |
I just created a new test Rails app (on 5.1.1) and confirmed this issue still exists. With the setup mentioned above, running the call generates the following SQL:
Notice that the |
Could you create a reproduction script with this template https://github.com/rails/rails/blob/master/guides/bug_report_templates/active_record_master.rb? |
Sure, how's this? https://gist.github.com/jrdioko/5b371da56604647e011da9e58235286b |
This is known behaviour; |
Using
#includes
to eager load a model that has already been eager loaded in a previous step causes ActiveRecord to unnecessarily fetch the models again. This means that eager loading must be done at a single top-level place in the code, rather than being able to add it to all the specific lower-level places where it is required (just like.transaction
calls can be added anywhere a transaction is required, and they will all join the parent transaction). See the example below:Steps to reproduce
Consider a simple case with three levels of associations:
This call illustrates the issue:
Expected behavior
The
includes(bars: :baz)
call should execute a database query to load bars and a query to load bazs. Theincludes(:baz)
calls should do nothing, since bazs have already been eager loaded.Actual behavior
Each
includes(:baz)
call (one per iteration in the loop) executes separate eager loading queries, despite the fact that bazs have already been eager loaded before entering the loop.System configuration
Rails version: 4.2.7.1
Ruby version: 2.3.1
The text was updated successfully, but these errors were encountered: