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 #48535]: fix behavior of proc_for_binds
in Arel::Nodes::HomogenousIn
#49050
Conversation
40d32f1
to
42ee8a2
Compare
1444b29
to
5627047
Compare
The description here says a lot about what the previous change did and what broke, but I've struggled to follow the reasoning of the change. Is the following accurate?
Does |
5627047
to
2acf113
Compare
2acf113
to
5627047
Compare
Sorry for the confusion, I ended up messing up my local and pushed without realizing, which ended up causing a bug in the bot. I'll be more careful |
ab31def
to
ad4506d
Compare
Yes, your conclusion is correct. And |
78b0001
to
a26277b
Compare
a26277b
to
9d6532f
Compare
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.
After digging into this, I think this solution is mostly on target. 👍 I've left a few comments, but I pushed a commit to address them since I was digging into the code anyway. I'll merge once the build is green.
activerecord/CHANGELOG.md
Outdated
* Fix behavior of `proc_for_binds` in `Arel::Nodes::HomogeneousIn` | ||
|
||
Previously, the `proc_for_binds` was introduced to address issues related to binds with null attribute names. However, this led to duplicated casting behavior, impacting searches involving casted attributes. This fix aims to resolve the issue using `FromDatabase`, mitigating casting issues while preserving the handling of null attribute names. |
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.
CHANGELOG entries are for users rather than Rails maintainers, so this should focus on how the user is affected instead of the implementation details.
-> value { ActiveModel::Attribute.with_cast_value(attribute.name, value, attribute.type_caster) } | ||
-> value { ActiveModel::Attribute.from_database(attribute.name, value, ActiveModel::Type.default_value) } |
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.
The fix here is actually due to changing attribute.type_caster
to ActiveModel::Type.default_value
because that changes the subsequent serialize
call into a no-op:
rails/activemodel/lib/active_model/type/value.rb
Lines 65 to 67 in a409c63
def serialize(value) | |
value | |
end |
As such, changing with_cast_value
to from_database
has no effect because the methods that differ between them (see WithCastValue
and FromDatabase
) aren't being called.
def test_where_in_binds_with_json_attribute | ||
Admin::User.where(json_options: [{ a: 1 }, { b: 2 }]).load | ||
wait | ||
assert_match(%{[["json_options", "{\\"a\\":1}"], ["json_options", "{\\"b\\":2}"]]}, @logger.logged(:debug).last) | ||
end |
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.
This tests the logging output, but what we're really trying to fix is the query, so I think we should test the query results instead.
Previously, `proc_for_binds` was introduced to address missing attribute names when logging binds. However, this causes double serialization, impacting searches involving serialized attributes. This commit fixes the issue by replacing the type with `ActiveModel::Type.default_value` so that the 2nd serialization is effectively a no-op. Fixes rails#48072. Fixes rails#48535. Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
9d6532f
to
fb5773b
Compare
Thank you, @JohnAnon9771! 🥛 Backported to |
Motivation / Background
This PR addresses the issues #48535 and #48072.
With the introduction of PR #41068, an unintended behavior surfaced, causing the
proc_for_binds
to apply casting to attributes that were already casted. Consequently, this led to the malfunctioning of queries, as noted in the referenced issues.This commit fixes the issue by replacing the type with
ActiveModel::Type.default_value
so that the 2nd serialization is effectively a no-op. This correction has obviated the need for changes such as "Fix deterministic queries that were broken after #41068," as detailed in this commit. These changes had inadvertently caused the tests initially intended forproc_for_binds
withinHomogeneousIn
to erroneously evaluate theproc_for_binds
withinInWithAdditionalValues
. This resulted in false positives whenever adjustments were made to theproc_for_binds
withinHomogeneousIn
.Fixes #48072.
Fixes #48535.
Checklist
Before submitting the PR make sure the following are checked:
[Fix #issue-number]