-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
ActiveRecord::Delegation leaks scope to inner queries on the same model #50760
Comments
This is the expected behavior. |
Just to be clear #50396 might change that, but right now this is the expected behavior. If that PR changes it we will have to document it, but at the moment this isn't an issue. |
Edit: side note of an issue that popped up along with it: It might be a good idea to document that passing a relation will result in immediate database access in How about adding a sentence like:
|
For anyone encountering this issue in the future, a workaround is to define the methods on -class ApplicationRecord
- def self.replica_find_each(...)
+class ActiveRecord::Relation
+ def replica_find_each(...)
ActiveRecord::Base.connected_to(role: :replica) do
find_each(...)
end
end
end
+ApplicationRecord.delegate :replica_find_each, to: :all This way, the method itself still uses the correct scope, but the scope does not leak into the method body or passed block. |
Steps to reproduce
Expected behavior
The inner query is
WHERE birth_date != <today>
and finds some users.Actual behavior
The inner query is
WHERE birth_date = <today> AND WHERE birth_date != <today>
and returns an empty relation.This is because the outer scoping (
where(birth_date: Date.today)
) is mixed into the inner query by this code.Ideas
The automatic scoping usually makes sense, e.g. you would want methods like this one to adapt correctly to Relations:
When doing inner queries, however, the resulting bugs can be quite subtle and hard to track down!
Idea 1: Warn for access to the same model within any given block in delegated relation methods?
Idea 2: Revert to the surrounding scoping inside any given block?
Idea 3: Deprecate delegation of class methods (non-scopes) through relations and add new helper(s) to define such methods instead - helper(s) that make it obvious whether or not scoping will be applied?
The text was updated successfully, but these errors were encountered: