Skip to content
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

Merged
merged 1 commit into from
Sep 4, 2023

Conversation

ippachi
Copy link
Contributor

@ippachi ippachi commented Apr 29, 2023

Motivation / Background

Fixes #48094
unscope not working when where by tripe dot range

Detail

Define fetch_attribute to activerecord/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:

  • 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.

@skipkayhil
Copy link
Member

The fix looks good to me. Can you add a CHANGELOG entry (and make sure you only have one commit after that)?

@@ -18,6 +18,12 @@ def right
children[1]
end

def fetch_attribute(&block)
children.each do |child|
Copy link
Contributor

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:

!Arel.fetch_attribute(node) { |attr| attr.relation.name == table.name }

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

Copy link
Contributor Author

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?

Copy link
Contributor

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) }

Copy link
Contributor Author

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

@ippachi
Copy link
Contributor Author

ippachi commented Jun 13, 2023

@nvasilevski @skipkayhil
I fixed code and added CHANGELOG entry

@kamipo kamipo merged commit 8271186 into rails:main Sep 4, 2023
8 checks passed
kamipo added a commit that referenced this pull request Sep 4, 2023
Fix unscope not working when where by tripe dot range
@ghiculescu
Copy link
Member

FYI #49463

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

Successfully merging this pull request may close these issues.

unscope not working when where by tripe dot range
5 participants