提交 621c2432 编写于 作者: A Aaron Patterson

keep a cache on the alias object

上级 a53c2bea
......@@ -85,10 +85,19 @@ 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)
......@@ -96,9 +105,9 @@ 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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册