From 502bc87fbaeb2917e3d7eb3d26badff887073c4e Mon Sep 17 00:00:00 2001 From: Melanie Gilman Date: Tue, 2 Dec 2014 11:04:38 -0500 Subject: Refactor `PredicateBuilder` from singleton to instance --- .../active_record/relation/predicate_builder.rb | 36 +++++++++++++--------- .../lib/active_record/relation/query_methods.rb | 4 +-- 2 files changed, 24 insertions(+), 16 deletions(-) (limited to 'activerecord/lib/active_record/relation') diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb index 938bf55c6d..a6da60b21a 100644 --- a/activerecord/lib/active_record/relation/predicate_builder.rb +++ b/activerecord/lib/active_record/relation/predicate_builder.rb @@ -5,7 +5,12 @@ module ActiveRecord autoload :RelationHandler, 'active_record/relation/predicate_builder/relation_handler' autoload :ArrayHandler, 'active_record/relation/predicate_builder/array_handler' - def self.resolve_column_aliases(klass, hash) + def initialize(klass, table) + @klass = klass + @table = table + end + + def resolve_column_aliases(hash) hash = hash.dup hash.keys.grep(Symbol) do |key| if klass.attribute_alias? key @@ -15,21 +20,21 @@ module ActiveRecord hash end - def self.build_from_hash(klass, attributes, default_table) + def build_from_hash(attributes) queries = [] + builder = self attributes.each do |column, value| - table = default_table - if value.is_a?(Hash) if value.empty? queries << '1=0' else - table = Arel::Table.new(column) + arel_table = Arel::Table.new(column) association = klass._reflect_on_association(column) + builder = self.class.new(association && association.klass, arel_table) value.each do |k, v| - queries.concat expand(association && association.klass, table, k, v) + queries.concat builder.expand(k, v) end end else @@ -37,17 +42,17 @@ module ActiveRecord if column.include?('.') table_name, column = column.split('.', 2) - table = Arel::Table.new(table_name) + arel_table = Arel::Table.new(table_name) + builder = self.class.new(klass, arel_table) end - - queries.concat expand(klass, table, column, value) + queries.concat builder.expand(column, value) end end queries end - def self.expand(klass, table, column, value) + def expand(column, value) queries = [] # Find the foreign key when using queries such as: @@ -57,17 +62,17 @@ module ActiveRecord # PriceEstimate.where(estimate_of: treasure) if klass && reflection = klass._reflect_on_association(column) if reflection.polymorphic? && base_class = polymorphic_base_class_from_value(value) - queries << build(table[reflection.foreign_type], base_class) + queries << self.class.build(table[reflection.foreign_type], base_class) end column = reflection.foreign_key end - queries << build(table[column], value) + queries << self.class.build(table[column], value) queries end - def self.polymorphic_base_class_from_value(value) + def polymorphic_base_class_from_value(value) case value when Relation value.klass.base_class @@ -116,11 +121,14 @@ module ActiveRecord def self.build(attribute, value) handler_for(value).call(attribute, value) end - private_class_method :build def self.handler_for(object) @handlers.detect { |klass, _| klass === object }.last end private_class_method :handler_for + + protected + + attr_reader :klass, :table end end diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index d58af01339..f166b6d5db 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -947,7 +947,7 @@ module ActiveRecord when String, Array [@klass.send(:sanitize_sql, other.empty? ? opts : ([opts] + other))] when Hash - opts = PredicateBuilder.resolve_column_aliases(klass, opts) + opts = predicate_builder.resolve_column_aliases(opts) tmp_opts, bind_values = create_binds(opts) self.bind_values += bind_values @@ -955,7 +955,7 @@ module ActiveRecord attributes = @klass.send(:expand_hash_conditions_for_aggregates, tmp_opts) add_relations_to_bind_values(attributes) - PredicateBuilder.build_from_hash(klass, attributes, table) + predicate_builder.build_from_hash(attributes) else [opts] end -- cgit v1.2.3