aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2013-10-14 18:37:18 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2013-10-14 18:37:18 -0700
commit621c24323ea3226206ed65a16070b97a24a5bc2f (patch)
tree5ba5f3ca4a388d8dfb31dea1737e99221dd16f22
parenta53c2beac42e0fea5dab9a334a066911beeba976 (diff)
downloadrails-621c24323ea3226206ed65a16070b97a24a5bc2f.tar.gz
rails-621c24323ea3226206ed65a16070b97a24a5bc2f.tar.bz2
rails-621c24323ea3226206ed65a16070b97a24a5bc2f.zip
keep a cache on the alias object
-rw-r--r--activerecord/lib/active_record/associations/join_dependency.rb32
-rw-r--r--activerecord/lib/active_record/associations/join_dependency/join_part.rb5
-rw-r--r--activerecord/lib/active_record/relation/finder_methods.rb2
3 files changed, 22 insertions, 17 deletions
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