Permalink
Browse files

keep a cache on the alias object

  • Loading branch information...
1 parent a53c2be commit 621c24323ea3226206ed65a16070b97a24a5bc2f @tenderlove tenderlove committed Oct 15, 2013
@@ -85,20 +85,29 @@ def join_constraints
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)
def table
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 @@ def aliases
}
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 @@ def instantiate(result_set)
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 @@ def build_join_association(reflection, parent, join_type)
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 @@ def construct(ar_parent, parent, row, rs, seen, model_cache)
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
@@ -51,11 +51,6 @@ def aliased_table_name
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
@@ -255,7 +255,7 @@ def find_with_associations
[]
else
rows = connection.select_all(relation.arel, 'SQL', relation.bind_values.dup)
- join_dependency.instantiate(rows)
+ join_dependency.instantiate(rows, aliases)
end
end
end

0 comments on commit 621c243

Please sign in to comment.