-
Notifications
You must be signed in to change notification settings - Fork 21.7k
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
Fix: ActiveRecord::Calculations#ids
returns duplicate ids
#46503
Conversation
082228a
to
df21f6f
Compare
e4b342b
to
b876c5c
Compare
5a2223f
to
5b575ba
Compare
e129452
to
a473cf9
Compare
a473cf9
to
bed0443
Compare
ActiveRecord::Calculations#ids
plucks included associations IDs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👋 Hey Joshua, thanks for picking this up!
Relying on the base relation makes sense to me, but I think #ids
should still rely on #pluck
, instead of extracting the pluck logic to #perform_pluck
and calling that directly from #ids
. #pluck
avoids making queries if the relation is already loaded:
def pluck(*column_names)
if loaded? && all_attributes?(column_names)
result = records.pluck(*column_names)
if @async
return Promise::Complete.new(result)
else
return result
end
end
...
end
So if we jump straight to the #perform_pluck
logic you've extracted when #ids
is called, we will always perform a query. What do you think about still using #pluck
in #ids
, but scoping to the base relation there, ie.
def ids
klass.pluck(primary_key)
end
?
fec35bb
to
0b32ebf
Compare
Thanks for the review! @adrianna-chang-shopify
This makes way more sense. I'm still getting used to how AR base classes are structured so thanks for the suggestion which I've now actioned. |
Ah, it's just the assertion that's wrong now that we're deduplicating ids, so 👍 |
4414979
to
2d44f66
Compare
Ah, yes scoping would be a problem 🤦♀️ Is there a reason not to do |
That is doing the deduplication on the Ruby side, that isn't ideal. Something like |
Ah, yeah that makes sense to me 👍 |
69434bb
to
3078167
Compare
I agree @adrianna-chang-shopify.
I'm happy to drop |
3078167
to
de0c9f2
Compare
de0c9f2
to
8fd3369
Compare
Nice work! Thank you. |
🤔 this adds |
I'm not sure this is something we should / need to change. But if we're going to, I think we need to take some more inspiration from the existing pluck tests, as the new implementation is no longer covered by them: def test_ids_if_table_included
c = Company.create!(name: "test", contracts: [Contract.new(developer_id: 7)])
assert_equal [c.id], Company.includes(:contracts).where("contracts.id" => c.contracts.first).ids
end |
This PR adds `async_ids` introduced at #46503 to 7_1_release_notes.
…iveRecordAllMethod` Follow up rails/rails#44446, rails/rails#37944, rails/rails#46503, and rails/rails#47010. This PR supports some Rails 7.1's new querying methods for `Rails/RedundantActiveRecordAllMethod`.
…iveRecordAllMethod` Follow up rails/rails#44446, rails/rails#37944, rails/rails#46503, and rails/rails#47010. This PR supports some Rails 7.1's new querying methods for `Rails/RedundantActiveRecordAllMethod`.
Motivation / Background
This Pull Request has been created to address #46455.
Detail
This Pull Request changes
ActiveRecord::Calculations#ids
to only return the unique ids of the base model, ignoring the join on eager loaded, preloaded and included associations.The cause for this was the join dependancy applied within
#pluck
when the relation contained preloads.#ids
has been updated to query the relation's foreign key itself rather than relying on#pluck
unless the records have already been loaded.Additional information
Checklist
Before submitting the PR make sure the following are checked:
[Fix #issue-number]