diff options
Diffstat (limited to 'activerecord/lib/active_record/associations/class_methods')
4 files changed, 36 insertions, 45 deletions
diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb index ce20420aad..78b634a26c 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -6,13 +6,15 @@ module ActiveRecord module Associations module ClassMethods class JoinDependency # :nodoc: - attr_reader :join_parts, :reflections, :alias_tracker + attr_reader :join_parts, :reflections, :alias_tracker, :active_record def initialize(base, associations, joins) - @join_parts = [JoinBase.new(base, joins)] - @associations = {} - @reflections = [] - @alias_tracker = AliasTracker.new(joins) + @active_record = base + @table_joins = joins + @join_parts = [JoinBase.new(base)] + @associations = {} + @reflections = [] + @alias_tracker = AliasTracker.new(joins) @alias_tracker.aliased_name_for(base.table_name) # Updates the count for base.table_name to 1 build(associations) end @@ -49,11 +51,11 @@ module ActiveRecord records = rows.map { |model| primary_id = model[primary_key] parent = parents[primary_id] ||= join_base.instantiate(model) - construct(parent, @associations, join_associations.dup, model) + construct(parent, @associations, join_associations, model) parent }.uniq - remove_duplicate_results!(join_base.active_record, records, @associations) + remove_duplicate_results!(active_record, records, @associations) records end @@ -122,7 +124,7 @@ module ActiveRecord build(association, parent, join_type) end when Hash - associations.keys.sort{|a,b|a.to_s<=>b.to_s}.each do |name| + associations.keys.sort_by { |a| a.to_s }.each do |name| join_association = build(name, parent, join_type) build(associations[name], join_association, join_type) end diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index ed2053d3df..5cc96a7aef 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -21,7 +21,7 @@ module ActiveRecord attr_reader :aliased_prefix delegate :options, :through_reflection, :source_reflection, :through_reflection_chain, :to => :reflection - delegate :table, :table_name, :to => :parent, :prefix => true + delegate :table, :table_name, :to => :parent, :prefix => :parent delegate :alias_tracker, :to => :join_dependency def initialize(reflection, join_dependency, parent = nil) @@ -50,7 +50,7 @@ module ActiveRecord def find_parent_in(other_join_dependency) other_join_dependency.join_parts.detect do |join_part| - self.parent == join_part + parent == join_part end end @@ -129,7 +129,15 @@ module ActiveRecord conditions << reflection_conditions(index, table) conditions << sti_conditions(reflection, table) - relation = relation.join(table, join_type).on(*conditions.flatten.compact) + ands = relation.create_and(conditions.flatten.compact) + + join = relation.create_join( + relation.froms.first, + table, + relation.create_on(ands), + join_type) + + relation = relation.from(join) # The current table in this iteration becomes the foreign table in the next foreign_table = table @@ -165,10 +173,6 @@ module ActiveRecord name end - def interpolate_sql(sql) - instance_eval("%@#{sql.gsub('@', '\@')}@", __FILE__, __LINE__) - end - private # Generate aliases and Arel::Table instances for each of the tables which we will @@ -181,10 +185,7 @@ module ActiveRecord table_alias_for(reflection, reflection != self.reflection) ) - table = Arel::Table.new( - reflection.table_name, :engine => arel_engine, - :as => aliased_table_name, :columns => reflection.klass.columns - ) + table = Arel::Table.new(reflection.table_name, :as => aliased_table_name) # For habtm, we have two Arel::Table instances related to a single reflection, so # we just store them as a pair in the array. @@ -199,10 +200,7 @@ module ActiveRecord table_alias_for(reflection, true) ) - join_table = Arel::Table.new( - join_table_name, :engine => arel_engine, - :as => aliased_join_table_name - ) + join_table = Arel::Table.new(join_table_name, :as => aliased_join_table_name) [table, join_table] else @@ -220,24 +218,23 @@ module ActiveRecord def reflection_conditions(index, table) @reflection.through_conditions.reverse[index].map do |condition| - Arel.sql(interpolate_sql(sanitize_sql( - condition, - table.table_alias || table.name - ))) + Arel.sql(sanitize_sql(condition, table.table_alias || table.name)) end end + def sanitize_sql(condition, table_name) + active_record.send(:sanitize_sql, condition, table_name) + end + def sti_conditions(reflection, table) unless reflection.klass.descends_from_active_record? - sti_column = table[reflection.klass.inheritance_column] - - condition = sti_column.eq(reflection.klass.sti_name) - - reflection.klass.descendants.each do |subclass| - condition = condition.or(sti_column.eq(subclass.sti_name)) - end + sti_column = table[reflection.klass.inheritance_column] + sti_condition = sti_column.eq(reflection.klass.sti_name) + subclasses = reflection.klass.descendants - condition + subclasses.inject(sti_condition) { |attr,subclass| + attr.or(sti_column.eq(subclass.sti_name)) + } end end diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_base.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_base.rb index ed05003f66..67567f06df 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_base.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_base.rb @@ -3,14 +3,6 @@ module ActiveRecord module ClassMethods class JoinDependency # :nodoc: class JoinBase < JoinPart # :nodoc: - # Extra joins provided when the JoinDependency was created - attr_reader :table_joins - - def initialize(active_record, joins = nil) - super(active_record) - @table_joins = joins - end - def ==(other) other.class == self.class && other.active_record == active_record @@ -21,7 +13,7 @@ module ActiveRecord end def table - Arel::Table.new(table_name, :engine => arel_engine, :columns => active_record.columns) + Arel::Table.new(table_name, arel_engine) end def aliased_table_name diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb index 0b093b65e9..cd16ae5a8b 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb @@ -14,7 +14,7 @@ module ActiveRecord # association. attr_reader :active_record - delegate :table_name, :column_names, :primary_key, :reflections, :sanitize_sql, :arel_engine, :to => :active_record + delegate :table_name, :column_names, :primary_key, :reflections, :arel_engine, :to => :active_record def initialize(active_record) @active_record = active_record |