From 621c24323ea3226206ed65a16070b97a24a5bc2f Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 14 Oct 2013 18:37:18 -0700 Subject: keep a cache on the alias object --- .../active_record/associations/join_dependency.rb | 32 ++++++++++++++-------- .../associations/join_dependency/join_part.rb | 5 ---- .../lib/active_record/relation/finder_methods.rb | 2 +- 3 files changed, 22 insertions(+), 17 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations/join_dependency.rb b/activerecord/lib/active_record/associations/join_dependency.rb index 2a558074d8..3141e6e850 100644 --- a/activerecord/lib/active_record/associations/join_dependency.rb +++ b/activerecord/lib/active_record/associations/join_dependency.rb @@ -85,10 +85,19 @@ module ActiveRecord class Aliases def initialize(tables) @tables = tables + @alias_cache = tables.each_with_object({}) { |table,h| + h[table.name] = table.columns.each_with_object({}) { |column,i| + i[column.name] = column.alias + } + } end def columns - @tables.flat_map { |t| t.columns } + @tables.flat_map { |t| t.column_aliases } + end + + def column_alias(table, column) + @alias_cache[table][column] end class Table < Struct.new(:name, :alias, :columns) @@ -96,9 +105,9 @@ module ActiveRecord Arel::Nodes::TableAlias.new name, self.alias end - def columns + def column_aliases t = table - super.map { |column| t[column.name].as Arel.sql column.alias } + columns.map { |column| t[column.name].as Arel.sql column.alias } end end Column = Struct.new(:name, :alias) @@ -113,8 +122,8 @@ module ActiveRecord } end - def instantiate(result_set) - primary_key = join_root.aliased_primary_key + def instantiate(result_set, aliases) + primary_key = aliases.column_alias(join_root.table, join_root.primary_key) type_caster = result_set.column_type primary_key seen = Hash.new { |h,parent_klass| @@ -131,7 +140,7 @@ module ActiveRecord result_set.each { |row_hash| primary_id = type_caster.type_cast row_hash[primary_key] parent = parents[primary_id] ||= join_root.instantiate(row_hash) - construct(parent, join_root, row_hash, result_set, seen, model_cache) + construct(parent, join_root, row_hash, result_set, seen, model_cache, aliases) } parents.values @@ -202,7 +211,7 @@ module ActiveRecord node end - def construct(ar_parent, parent, row, rs, seen, model_cache) + def construct(ar_parent, parent, row, rs, seen, model_cache, aliases) primary_id = ar_parent.id parent.children.each do |node| @@ -212,22 +221,23 @@ module ActiveRecord else if ar_parent.association_cache.key?(node.reflection.name) model = ar_parent.association(node.reflection.name).target - construct(model, node, row, rs, seen, model_cache) + construct(model, node, row, rs, seen, model_cache, aliases) next end end - id = row[node.aliased_primary_key] + key = aliases.column_alias(node.table, node.primary_key) + id = row[key] next if id.nil? model = seen[parent.base_klass][primary_id][node.base_klass][id] if model - construct(model, node, row, rs, seen, model_cache) + construct(model, node, row, rs, seen, model_cache, aliases) else model = construct_model(ar_parent, node, row, model_cache, id) seen[parent.base_klass][primary_id][node.base_klass][id] = model - construct(model, node, row, rs, seen, model_cache) + construct(model, node, row, rs, seen, model_cache, aliases) end end end diff --git a/activerecord/lib/active_record/associations/join_dependency/join_part.rb b/activerecord/lib/active_record/associations/join_dependency/join_part.rb index 2c4111e5ed..476288b7c5 100644 --- a/activerecord/lib/active_record/associations/join_dependency/join_part.rb +++ b/activerecord/lib/active_record/associations/join_dependency/join_part.rb @@ -51,11 +51,6 @@ module ActiveRecord raise NotImplementedError end - # The alias for the primary key of the active_record's table - def aliased_primary_key - "#{aliased_prefix}_r0" - end - # An array of [column_name, alias] pairs for the table def column_names_with_alias unless @column_names_with_alias diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 5e11ba0325..f7f60635d3 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -255,7 +255,7 @@ module ActiveRecord [] else rows = connection.select_all(relation.arel, 'SQL', relation.bind_values.dup) - join_dependency.instantiate(rows) + join_dependency.instantiate(rows, aliases) end end end -- cgit v1.2.3