-
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
Fix unscope not working when where by tripe dot range #48095
Conversation
The fix looks good to me. Can you add a CHANGELOG entry (and make sure you only have one commit after that)? |
activerecord/lib/arel/nodes/and.rb
Outdated
@@ -18,6 +18,12 @@ def right | |||
children[1] | |||
end | |||
|
|||
def fetch_attribute(&block) | |||
children.each do |child| |
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.
We are doing something wrong here. I'm not familiar with the area to immediately tell what is wrong but in some cases .fetch_attribute
is expected to return a boolean, for example:
rails/activerecord/lib/active_record/associations/join_dependency/join_association.rb
Line 60 in 1f773fa
!Arel.fetch_attribute(node) { |attr| attr.relation.name == table.name } |
rails/activerecord/lib/arel/nodes/binary.rb
Line 116 in 1f773fa
left.fetch_attribute(&block) && right.fetch_attribute(&block) |
end || Arel.fetch_attribute(node) do |attr| |
But by using .each
here we will always return the value we enumerate over which is children
and it'll always be truthy. It may or may not be the issue but I wanted to point out that this implementation of fetch_attribute
doesn't seem to be consistent with how we expect to use it
because unscope uses fetch_attribute to determine whether to exclude predicate or not.
Could you elaborate on this a little bit? Because if it makes decision based on the return value then the implementation seems wrong as the return value will always be truthy
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.
I looked over the code
As you said, fetch_attribute should return a boolean value
fetch_attribute seems to be a method that determines whether the return value of the block is true for all attributes it owns
So it seems correct to use all?
instead of each
this time. What do you think?
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.
I think .all?
seems to be more aligned with the expected behavior however be careful with [].all?
being true
.
We may want to additionally check for children.any?
So perhaps
children.any? && children.all? { |child| child.fetch_attribute(&block) }
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.
You are right
I don't know if there are cases where the children
are empty, but in any case it would be better to take empty cases into consideration
I will amend it as such and at the same time add an entry in CHANGELOG
80cb6f2
to
ed68048
Compare
@nvasilevski @skipkayhil |
Fix unscope not working when where by tripe dot range
FYI #49463 |
Motivation / Background
Fixes #48094
unscope
not working when where by tripe dot rangeDetail
Define
fetch_attribute
toactiverecord/lib/arel/nodes/and.rb
, because unscope uses fetch_attribute to determine whether to exclude predicate or not.Checklist
Before submitting the PR make sure the following are checked:
[Fix #issue-number]