aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2013-10-08 17:07:08 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2013-10-08 17:23:53 -0700
commit868457488d3c43ff4e9c28e34883620d90345185 (patch)
tree1495edb1d3b93e417f5fe644b755480a7caa6e82
parent6484ab2f8bfa4286e557bab5350cc8de16cf8bb2 (diff)
downloadrails-868457488d3c43ff4e9c28e34883620d90345185.tar.gz
rails-868457488d3c43ff4e9c28e34883620d90345185.tar.bz2
rails-868457488d3c43ff4e9c28e34883620d90345185.zip
generate the association hash from the top down
This prevents us from walking back up the parent tree once for each leaf.
-rw-r--r--activerecord/lib/active_record/associations/join_dependency.rb32
1 files changed, 15 insertions, 17 deletions
diff --git a/activerecord/lib/active_record/associations/join_dependency.rb b/activerecord/lib/active_record/associations/join_dependency.rb
index ce6cd1461a..7df89ba360 100644
--- a/activerecord/lib/active_record/associations/join_dependency.rb
+++ b/activerecord/lib/active_record/associations/join_dependency.rb
@@ -71,6 +71,10 @@ module ActiveRecord
@children = []
end
+ def association_hash
+ association_hash_iter children, {}
+ end
+
def each
yield self
iter = lambda { |list|
@@ -81,6 +85,15 @@ module ActiveRecord
}
iter.call children
end
+
+ private
+ def association_hash_iter nodes, acc
+ nodes.each { |node|
+ h = acc[node.join_part.reflection.name] ||= {}
+ association_hash_iter node.children, h
+ }
+ acc
+ end
end
def join_parts
@@ -93,7 +106,7 @@ module ActiveRecord
associations.reject { |association|
join_assocs.detect { |a| association == a }
}.each { |association|
- join_node = find_parent_node(association.parent) || @join_part
+ join_node = find_parent_node(association.parent) || @join_parts
type = association.join_type
find_or_build_scalar association.reflection, join_node, type
}
@@ -144,9 +157,7 @@ module ActiveRecord
private
def associations
- join_associations.each_with_object({}) do |assoc, tree|
- cache_joined_association assoc, tree
- end
+ @join_parts.association_hash
end
def find_parent_node(parent)
@@ -187,19 +198,6 @@ module ActiveRecord
end
end
- def cache_joined_association(association, tree)
- associations = []
- parent = association.parent
- while parent != join_base
- associations.unshift(parent.reflection.name)
- parent = parent.parent
- end
- ref = associations.inject(tree) do |cache,key|
- cache[key]
- end
- ref[association.reflection.name] ||= {}
- end
-
def find_reflection(klass, name)
klass.reflect_on_association(name.intern) or
raise ConfigurationError, "Association named '#{ name }' was not found on #{ klass.name }; perhaps you misspelled it?"