aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder.rb8
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/array_handler.rb14
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb25
3 files changed, 19 insertions, 28 deletions
diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb
index 58d30b801c..f2e719363c 100644
--- a/activerecord/lib/active_record/relation/predicate_builder.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder.rb
@@ -20,7 +20,6 @@ module ActiveRecord
register_handler(RangeHandler::RangeWithBinds, RangeHandler.new)
register_handler(Relation, RelationHandler.new)
register_handler(Array, ArrayHandler.new(self))
- register_handler(PolymorphicArrayValue, PolymorphicArrayHandler.new(self))
end
def build_from_hash(attributes)
@@ -101,14 +100,17 @@ module ActiveRecord
if associated_table.polymorphic_association?
case value.is_a?(Array) ? value.first : value
when Base, Relation
- binds.concat(value.bound_attributes) if value.is_a?(Relation)
value = [value] unless value.is_a?(Array)
klass = PolymorphicArrayValue
end
end
if klass
- result[column_name] = klass.new(associated_table, value)
+ result[column_name] = klass.new(associated_table, value).queries.map do |query|
+ attrs, bvs = create_binds_for_hash(query)
+ binds.concat(bvs)
+ attrs
+ end
else
queries = AssociationQueryValue.new(associated_table, value).queries
attrs, bvs = create_binds_for_hash(queries)
diff --git a/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb
index 88b6c37d43..54e9910598 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb
@@ -10,6 +10,7 @@ module ActiveRecord
nils, values = values.partition(&:nil?)
return attribute.in([]) if values.empty? && nils.empty?
+ return queries_predicates(values) if nils.empty? && values.all? { |v| v.is_a?(Hash) }
ranges, values = values.partition { |v| v.is_a?(Range) }
@@ -26,7 +27,7 @@ module ActiveRecord
array_predicates = ranges.map { |range| predicate_builder.build(attribute, range) }
array_predicates.unshift(values_predicate)
- array_predicates.inject { |composite, predicate| composite.or(predicate) }
+ array_predicates.inject(&:or)
end
# TODO Change this to private once we've dropped Ruby 2.2 support.
@@ -40,6 +41,17 @@ module ActiveRecord
other
end
end
+
+ private
+ def queries_predicates(queries)
+ if queries.size > 1
+ queries.map do |query|
+ Arel::Nodes::And.new(predicate_builder.build_from_hash(query))
+ end.inject(&:or)
+ else
+ predicate_builder.build_from_hash(queries.first)
+ end
+ end
end
end
end
diff --git a/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb
index c2f136256b..9bb2f8c8dc 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb
@@ -1,28 +1,5 @@
module ActiveRecord
class PredicateBuilder
- class PolymorphicArrayHandler # :nodoc:
- def initialize(predicate_builder)
- @predicate_builder = predicate_builder
- end
-
- def call(attribute, value)
- predicates = value.queries.map { |query| predicate_builder.build_from_hash(query) }
-
- if predicates.size > 1
- type_and_ids_predicates = predicates.map { |type_predicate, id_predicate| Arel::Nodes::Grouping.new(type_predicate.and(id_predicate)) }
- type_and_ids_predicates.inject(&:or)
- else
- predicates.first
- end
- end
-
- # TODO Change this to private once we've dropped Ruby 2.2 support.
- # Workaround for Ruby 2.2 "private attribute?" warning.
- protected
-
- attr_reader :predicate_builder
- end
-
class PolymorphicArrayValue # :nodoc:
attr_reader :associated_table, :values
@@ -35,7 +12,7 @@ module ActiveRecord
type_to_ids_mapping.map do |type, ids|
{
associated_table.association_foreign_type.to_s => type,
- associated_table.association_foreign_key.to_s => ids
+ associated_table.association_foreign_key.to_s => ids.size > 1 ? ids : ids.first
}
end
end