Skip to content

Commit

Permalink
Fix HomogeneousIn for serialized attributes
Browse files Browse the repository at this point in the history
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 #48072.
Fixes #48535.

Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
  • Loading branch information
JohnAnon9771 and jonathanhefner committed Nov 9, 2023
1 parent a409c63 commit fb5773b
Show file tree
Hide file tree
Showing 4 changed files with 8 additions and 17 deletions.
6 changes: 6 additions & 0 deletions activerecord/CHANGELOG.md
@@ -1,3 +1,9 @@
* Fix `where(field: values)` queries when `field` is a serialized attribute
(for example, when `field` uses `ActiveRecord::Base.serialize` or is a JSON
column).

*João Alves*

* Make the output of `ActiveRecord::Core#inspect` configurable.

By default, calling `inspect` on a record will yield a formatted string including just the `id`.
Expand Down
Expand Up @@ -28,7 +28,6 @@ def self.install_support
ActiveRecord::Relation.prepend(RelationQueries)
ActiveRecord::Base.include(CoreQueries)
ActiveRecord::Encryption::EncryptedAttributeType.prepend(ExtendedEncryptableType)
Arel::Nodes::HomogeneousIn.prepend(InWithAdditionalValues)
end

# When modifying this file run performance tests in
Expand Down Expand Up @@ -153,20 +152,6 @@ def serialize(data)
end
end
end

module InWithAdditionalValues
def proc_for_binds
-> value { ActiveModel::Attribute.with_cast_value(attribute.name, value, encryption_aware_type_caster) }
end

def encryption_aware_type_caster
if attribute.type_caster.is_a?(ActiveRecord::Encryption::EncryptedAttributeType)
attribute.type_caster.cast_type
else
attribute.type_caster
end
end
end
end
end
end
2 changes: 1 addition & 1 deletion activerecord/lib/arel/nodes/homogeneous_in.rb
Expand Up @@ -48,7 +48,7 @@ def casted_values
end

def proc_for_binds
-> value { ActiveModel::Attribute.with_cast_value(attribute.name, value, attribute.type_caster) }
-> value { ActiveModel::Attribute.with_cast_value(attribute.name, value, ActiveModel::Type.default_value) }
end

def fetch_attribute(&block)
Expand Down
2 changes: 1 addition & 1 deletion activerecord/test/cases/serialized_attribute_test.rb
Expand Up @@ -245,7 +245,7 @@ def test_where_by_serialized_attribute_with_hash_in_array
settings = { "color" => "green" }
Topic.serialize(:content, type: Hash)
topic = Topic.create!(content: settings)
assert_equal topic, Topic.where(content: [settings]).take
assert_equal topic, Topic.where(content: [settings, { "herring" => "red" }]).take
end

def test_serialized_default_class
Expand Down

0 comments on commit fb5773b

Please sign in to comment.