diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2018-01-29 08:34:33 +0900 |
---|---|---|
committer | Ryuta Kamizono <kamipo@gmail.com> | 2018-01-29 09:24:14 +0900 |
commit | 159b21b59dba120e58eeb8bff89b9d322e720c44 (patch) | |
tree | 4961855b5e5d01f0dd9332869f94539b81422caa /activerecord/lib/active_record | |
parent | 6b8c161fc2cabdadd33826d21f9bd099041b8069 (diff) | |
download | rails-159b21b59dba120e58eeb8bff89b9d322e720c44.tar.gz rails-159b21b59dba120e58eeb8bff89b9d322e720c44.tar.bz2 rails-159b21b59dba120e58eeb8bff89b9d322e720c44.zip |
Fix expanding an array of `composed_of` objects which have multiple mappings
Follow up of #31724.
If `composed_of` objects have multiple mappings, array predicate handler
can not correctly handle the expanded condition.
We need to handle it like polymorphic association objects.
Diffstat (limited to 'activerecord/lib/active_record')
3 files changed, 20 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb index 885c26d7aa..f3286846d2 100644 --- a/activerecord/lib/active_record/relation/predicate_builder.rb +++ b/activerecord/lib/active_record/relation/predicate_builder.rb @@ -86,6 +86,18 @@ module ActiveRecord expand_from_hash(query).reduce(&:and) end queries.reduce(&:or) + elsif table.aggregated_with?(key) + mapping = table.reflect_on_aggregation(key).mapping + queries = Array.wrap(value).map do |object| + mapping.map do |field_attr, aggregate_attr| + if mapping.size == 1 && !object.respond_to?(aggregate_attr) + build(table.arel_attribute(field_attr), object) + else + build(table.arel_attribute(field_attr), object.send(aggregate_attr)) + end + end.reduce(&:and) + end + queries.reduce(&:or) # FIXME: Deprecate this and provide a public API to force equality elsif (value.is_a?(Range) || value.is_a?(Array)) && table.type(key.to_s).respond_to?(:subtype) diff --git a/activerecord/lib/active_record/relation/where_clause_factory.rb b/activerecord/lib/active_record/relation/where_clause_factory.rb index 4ae94f4bfe..92b720068c 100644 --- a/activerecord/lib/active_record/relation/where_clause_factory.rb +++ b/activerecord/lib/active_record/relation/where_clause_factory.rb @@ -14,7 +14,6 @@ module ActiveRecord parts = [klass.sanitize_sql(other.empty? ? opts : ([opts] + other))] when Hash attributes = predicate_builder.resolve_column_aliases(opts) - attributes = klass.send(:expand_hash_conditions_for_aggregates, attributes) attributes.stringify_keys! parts = predicate_builder.build_from_hash(attributes) diff --git a/activerecord/lib/active_record/table_metadata.rb b/activerecord/lib/active_record/table_metadata.rb index 0459cbdc59..507f08a974 100644 --- a/activerecord/lib/active_record/table_metadata.rb +++ b/activerecord/lib/active_record/table_metadata.rb @@ -65,6 +65,14 @@ module ActiveRecord association && association.polymorphic? end + def aggregated_with?(aggregation_name) + klass && reflect_on_aggregation(aggregation_name) + end + + def reflect_on_aggregation(aggregation_name) + klass.reflect_on_aggregation(aggregation_name) + end + # TODO Change this to private once we've dropped Ruby 2.2 support. # Workaround for Ruby 2.2 "private attribute?" warning. protected |