diff options
Diffstat (limited to 'activerecord/lib/active_record/associations/class_methods/join_dependency.rb')
-rw-r--r-- | activerecord/lib/active_record/associations/class_methods/join_dependency.rb | 37 |
1 files changed, 27 insertions, 10 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 c578845878..13576e1aec 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -6,14 +6,17 @@ module ActiveRecord module Associations module ClassMethods class JoinDependency # :nodoc: - attr_reader :join_parts, :reflections, :table_aliases + attr_reader :join_parts, :reflections, :table_aliases, :active_record def initialize(base, associations, joins) - @table_joins = joins || '' + @active_record = base + @table_joins = joins @join_parts = [JoinBase.new(base)] @associations = {} @reflections = [] - @table_aliases = Hash.new(0) + @table_aliases = Hash.new do |h,name| + h[name] = count_aliases_from_table_joins(name) + end @table_aliases[base.table_name] = 1 build(associations) end @@ -44,12 +47,26 @@ module ActiveRecord end def count_aliases_from_table_joins(name) + return 0 if !@table_joins || Arel::Table === @table_joins + + @table_joins.grep(Arel::Nodes::Join).map { |join| + right = join.right + case right + when Arel::Table + right.name.downcase == name ? 1 : 0 + when String + count_aliases_from_string(right.downcase, name) + else + 0 + end + }.sum + end + + def count_aliases_from_string(join_sql, name) # quoted_name should be downcased as some database adapters (Oracle) return quoted name in uppercase - quoted_name = join_base.active_record.connection.quote_table_name(name.downcase).downcase - join_sql = @table_joins.downcase - join_sql.blank? ? 0 : - # Table names - join_sql.scan(/join(?:\s+\w+)?\s+#{quoted_name}\son/).size + + quoted_name = active_record.connection.quote_table_name(name.downcase).downcase + # Table names + join_sql.scan(/join(?:\s+\w+)?\s+#{quoted_name}\son/).size + # Table aliases join_sql.scan(/join(?:\s+\w+)?\s+\S+\s+#{quoted_name}\son/).size end @@ -61,11 +78,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 |