Skip to content

Fix: Incorrectly preloading through association records when middle association has been loaded #46579

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

Merged

Conversation

joshuay03
Copy link
Contributor

@joshuay03 joshuay03 commented Nov 25, 2022

Fix: #45822

This Pull Request has been created to address #45822.

Update: Looks like this also resolves #45542.

Detail

This Pull Request fixes ActiveRecord::Associations::Preloader::ThroughAssociation#records_by_owner to:

  1. successfully fetch the loaded source records for an already loaded middle record
  2. do so without performing unnecessary queries

RE: 1
Using a failing test and some logging, I found that the memoized keys in source_records_by_owner had different object_ids to the values in through_records_by_owner at the point at which the value was fetched using source_records_by_owner[record] and was therefore returning nil.

This was being caused by def middle_records loading new objects into @preloaded_records which would get passed in as the records for the source preloader, rather than using the already loaded through objects in through_records_by_owner.

This resulted in the source_records_by_owner hash containing keys which were different objects to the values in the through_records_by_owner hash.

RE: 2
This also happens to fix a circular dependency of sorts, since def middle_records would eventually call def source_preloaders while already in a previous call to it originating from def source_records_by_owner, causing the through record/s to reload and the source record/s to load, before finally loading the source records once again. These extra queries are visible in my comment below.

Additional information

Checklist

Before submitting the PR make sure the following are checked:

  • This Pull Request is related to one change. Changes that are unrelated should be opened in separate PRs.
  • Commit message has a detailed description of what changed and why. If this PR fixes a related issue include it in the commit message. Ex: [Fix #issue-number]
  • Tests are added or updated if you fix a bug or add a feature.
  • CHANGELOG files are updated for the changed libraries if there is a behavior change or additional feature. Minor bug fixes and documentation changes should not be included.
  • CI is passing.

@joshuay03 joshuay03 changed the title [Fix 45822] Fix through association incorrect preloading Fix: through association incorrect preloading Nov 25, 2022
@joshuay03 joshuay03 force-pushed the fix-through-association-incorrect-preloading branch from 54d8dd8 to 1fd3021 Compare November 25, 2022 15:41
@joshuay03 joshuay03 force-pushed the fix-through-association-incorrect-preloading branch from 1fd3021 to 3758d99 Compare November 26, 2022 08:31
@joshuay03 joshuay03 changed the title Fix: through association incorrect preloading Fix: Through association incorrect preloading Nov 26, 2022
@joshuay03 joshuay03 force-pushed the fix-through-association-incorrect-preloading branch 19 times, most recently from b657cbe to c540b36 Compare November 30, 2022 14:37
@joshuay03 joshuay03 force-pushed the fix-through-association-incorrect-preloading branch 3 times, most recently from 498cbc2 to fc76bf3 Compare December 17, 2022 13:04
end

assert_no_queries do
assert_equal expected_member_detail_ids.sort, member.organization_member_details_2.map(&:id).sort
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fails without the fix above
Screenshot 2022-11-30 at 6 39 00 pm

member.reload.organization # load through record

assert_queries(1) do
ActiveRecord::Associations::Preloader.new(records: [member], associations: :organization_member_details_2).call
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Down from 3 queries to 1 🎉
Screenshot 2022-11-30 at 6 28 56 pm

@joshuay03 joshuay03 force-pushed the fix-through-association-incorrect-preloading branch from fc76bf3 to 5eb9443 Compare December 17, 2022 13:13
@joshuay03 joshuay03 changed the title Fix: Through association incorrect preloading Fix: Incorrect through association preloading Dec 17, 2022
@joshuay03 joshuay03 changed the title Fix: Incorrect through association preloading Fix: Incorrect preloaded through records when middle association is loaded Dec 20, 2022
@joshuay03 joshuay03 changed the title Fix: Incorrect preloaded through records when middle association is loaded Fix: Incorrectly preloading through association records when middle association is preloaded Dec 20, 2022
@joshuay03 joshuay03 force-pushed the fix-through-association-incorrect-preloading branch from 5eb9443 to 85e404e Compare December 20, 2022 01:31
@joshuay03 joshuay03 changed the title Fix: Incorrectly preloading through association records when middle association is preloaded Fix: Incorrectly preloading through association records when middle association has been loaded Dec 20, 2022
@joshuay03 joshuay03 force-pushed the fix-through-association-incorrect-preloading branch from 85e404e to 18f8335 Compare December 20, 2022 03:23
@zzak
Copy link
Member

zzak commented Jan 18, 2023

FWIW, I've confirmed this fixes the issue described in #45542, but I'm not authoritative enough to say whether or not it's a real bug.

@joshuay03
Copy link
Contributor Author

joshuay03 commented Jan 18, 2023

FWIW, I've confirmed this fixes the issue described in #45542, but I'm not authoritative enough to say whether or not it's a real bug.

@zzak Thanks! I've updated the PR description with this issue too.

@such
Copy link

such commented Jan 18, 2023

This looks great! Thanks!

@joshuay03 joshuay03 force-pushed the fix-through-association-incorrect-preloading branch 2 times, most recently from d472cb9 to 4ab9e84 Compare February 17, 2023 21:39
@joshuay03 joshuay03 force-pushed the fix-through-association-incorrect-preloading branch from 4ab9e84 to 0178e1d Compare February 17, 2023 21:40
@byroot byroot merged commit 136066f into rails:main Feb 21, 2023
@joshuay03 joshuay03 deleted the fix-through-association-incorrect-preloading branch February 21, 2023 21:49
@joshuay03
Copy link
Contributor Author

Cheers! @byroot

@yopzer
Copy link

yopzer commented Mar 8, 2023

Hi, Thanks for the fix, this issue was blocking application I work on from upgrading to Rails 7.0. If I understand correctly how rails releases work, this fix will be included in Rails 7.1 release as it was merged in rails:main branch and the work on 7.1 is already in progress. Any chances getting this in 7.0?

byroot added a commit that referenced this pull request Mar 8, 2023
…rrect-preloading

Fix: Incorrectly preloading through association records when middle association has been loaded
@byroot
Copy link
Member

byroot commented Mar 8, 2023

I just backported it in 7-0-stable as 99ee8bd.

You can point your Gemfile at this branch.

@yopzer
Copy link

yopzer commented Mar 8, 2023

Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants