aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/relation/predicate_builder
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/relation/predicate_builder')
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/array_handler.rb22
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb13
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/base_handler.rb4
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/basic_object_handler.rb13
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb13
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/range_handler.rb28
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/relation_handler.rb6
7 files changed, 67 insertions, 32 deletions
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 1068e700e2..2fd75c8958 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActiveRecord
class PredicateBuilder
class ArrayHandler # :nodoc:
@@ -7,7 +9,6 @@ module ActiveRecord
def call(attribute, value)
return attribute.in([]) if value.empty?
- return queries_predicates(value) if value.all? { |v| v.is_a?(Hash) }
values = value.map { |x| x.is_a?(Base) ? x.id : x }
nils, values = values.partition(&:nil?)
@@ -17,7 +18,11 @@ module ActiveRecord
case values.length
when 0 then NullPredicate
when 1 then predicate_builder.build(attribute, values.first)
- else attribute.in(values)
+ else
+ bind_values = values.map do |v|
+ predicate_builder.build_bind_attribute(attribute.name, v)
+ end
+ attribute.in(bind_values)
end
unless nils.empty?
@@ -29,8 +34,6 @@ module ActiveRecord
array_predicates.inject(&:or)
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
@@ -40,17 +43,6 @@ 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/association_query_value.rb b/activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb
index 2fe0f81cab..28c7483c95 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb
@@ -1,17 +1,22 @@
+# frozen_string_literal: true
+
module ActiveRecord
class PredicateBuilder
class AssociationQueryValue # :nodoc:
- attr_reader :associated_table, :value
-
def initialize(associated_table, value)
@associated_table = associated_table
@value = value
end
def queries
- [associated_table.association_foreign_key.to_s => ids]
+ [associated_table.association_join_foreign_key.to_s => ids]
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 :associated_table, :value
+
private
def ids
case value
@@ -25,7 +30,7 @@ module ActiveRecord
end
def primary_key
- associated_table.association_primary_key
+ associated_table.association_join_primary_key
end
def convert_to_id(value)
diff --git a/activerecord/lib/active_record/relation/predicate_builder/base_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/base_handler.rb
index 3bb1037885..112821135f 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/base_handler.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/base_handler.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActiveRecord
class PredicateBuilder
class BaseHandler # :nodoc:
@@ -9,8 +11,6 @@ module ActiveRecord
predicate_builder.build(attribute, value.id)
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
diff --git a/activerecord/lib/active_record/relation/predicate_builder/basic_object_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/basic_object_handler.rb
index 79cde00303..34db266f05 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/basic_object_handler.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/basic_object_handler.rb
@@ -1,9 +1,20 @@
+# frozen_string_literal: true
+
module ActiveRecord
class PredicateBuilder
class BasicObjectHandler # :nodoc:
+ def initialize(predicate_builder)
+ @predicate_builder = predicate_builder
+ end
+
def call(attribute, value)
- attribute.eq(value)
+ bind = predicate_builder.build_bind_attribute(attribute.name, value)
+ attribute.eq(bind)
end
+
+ protected
+
+ attr_reader :predicate_builder
end
end
end
diff --git a/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb b/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb
index 9bb2f8c8dc..e8e2f2c626 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb
@@ -1,8 +1,8 @@
+# frozen_string_literal: true
+
module ActiveRecord
class PredicateBuilder
class PolymorphicArrayValue # :nodoc:
- attr_reader :associated_table, :values
-
def initialize(associated_table, values)
@associated_table = associated_table
@values = values
@@ -12,11 +12,16 @@ 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.size > 1 ? ids : ids.first
+ associated_table.association_foreign_key.to_s => ids
}
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 :associated_table, :values
+
private
def type_to_ids_mapping
default_hash = Hash.new { |hsh, key| hsh[key] = [] }
@@ -24,7 +29,7 @@ module ActiveRecord
end
def primary_key(value)
- associated_table.association_primary_key(base_class(value))
+ associated_table.association_join_primary_key(base_class(value))
end
def base_class(value)
diff --git a/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb
index 5db778e19c..6d16579708 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb
@@ -1,25 +1,41 @@
+# frozen_string_literal: true
+
module ActiveRecord
class PredicateBuilder
class RangeHandler # :nodoc:
- RangeWithBinds = Struct.new(:begin, :end, :exclude_end?)
+ class RangeWithBinds < Struct.new(:begin, :end)
+ def exclude_end?
+ false
+ end
+ end
+
+ def initialize(predicate_builder)
+ @predicate_builder = predicate_builder
+ end
def call(attribute, value)
+ begin_bind = predicate_builder.build_bind_attribute(attribute.name, value.begin)
+ end_bind = predicate_builder.build_bind_attribute(attribute.name, value.end)
if value.begin.respond_to?(:infinite?) && value.begin.infinite?
if value.end.respond_to?(:infinite?) && value.end.infinite?
attribute.not_in([])
elsif value.exclude_end?
- attribute.lt(value.end)
+ attribute.lt(end_bind)
else
- attribute.lteq(value.end)
+ attribute.lteq(end_bind)
end
elsif value.end.respond_to?(:infinite?) && value.end.infinite?
- attribute.gteq(value.begin)
+ attribute.gteq(begin_bind)
elsif value.exclude_end?
- attribute.gteq(value.begin).and(attribute.lt(value.end))
+ attribute.gteq(begin_bind).and(attribute.lt(end_bind))
else
- attribute.between(value)
+ attribute.between(RangeWithBinds.new(begin_bind, end_bind))
end
end
+
+ protected
+
+ attr_reader :predicate_builder
end
end
end
diff --git a/activerecord/lib/active_record/relation/predicate_builder/relation_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/relation_handler.rb
index 8a910a82fe..c8bbfa5051 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/relation_handler.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/relation_handler.rb
@@ -1,7 +1,13 @@
+# frozen_string_literal: true
+
module ActiveRecord
class PredicateBuilder
class RelationHandler # :nodoc:
def call(attribute, value)
+ if value.eager_loading?
+ value = value.send(:apply_join_dependency)
+ end
+
if value.select_values.empty?
value = value.select(value.arel_attribute(value.klass.primary_key))
end