From 45f911f30d698886c1f4e5159d3dcba9b4a80bee Mon Sep 17 00:00:00 2001 From: Anatoliy Lysenko Date: Sat, 23 Oct 2010 23:07:59 +0300 Subject: [PATCH 3/3] Fix eager loading of duplicated associations. --- activerecord/lib/active_record/associations.rb | 10 ++++++---- .../associations/cascaded_eager_loading_test.rb | 5 +++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index e774c70..57fb04e 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1923,18 +1923,20 @@ module ActiveRecord when Symbol, String reflection = parent.reflections[associations.to_s.intern] or raise ConfigurationError, "Association named '#{ associations }' was not found; perhaps you misspelled it?" + existed_join = join_associations.detect{ |j| j.parent == parent && j.reflection == reflection} + return existed_join unless existed_join.nil? @reflections << reflection join_association = build_join_association(reflection, parent) join_association.join_type = join_type @join_parts << join_association + return join_association when Array associations.each do |association| build(association, parent, join_type) end when Hash associations.keys.sort{|a,b|a.to_s<=>b.to_s}.each do |name| - build(name, parent, join_type) - build(associations[name], nil, join_type) + build(associations[name], build(name, parent, join_type), join_type) end else raise ConfigurationError, associations.inspect @@ -2013,7 +2015,7 @@ module ActiveRecord end # A JoinPart represents a part of a JoinDependency. It is an abstract class, inherited - # by JoinBase and JoinAssociation. A JoinBase represents the Active Record which + # by JoinBase and JoinAssociation. A JoinBase represents the Active Record which # everything else is being joined onto. A JoinAssociation represents an association which # is joining to the base. A JoinAssociation may result in more than one actual join # operations (for example a has_and_belongs_to_many JoinAssociation would result in @@ -2113,7 +2115,7 @@ module ActiveRecord attr_reader :reflection # The JoinDependency object which this JoinAssociation exists within. This is mainly - # relevant for generating aliases which do not conflict with other joins which are + # relevant for generating aliases which do not conflict with other joins which are # part of the query. attr_reader :join_dependency diff --git a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb index 5cc42a8..e3af341 100644 --- a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb +++ b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb @@ -52,6 +52,11 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase assert_nothing_raised { categories.all } end + def test_cascaded_eager_association_loading_with_twice_includes_edge_cases + assert_nothing_raised { Category.includes({:posts=>:author}).includes({:posts=>:comments}).where("posts.id is not null").all } + assert_nothing_raised { Category.includes(:posts, :categorizations).includes({:posts=>:comments }).where("posts.id is not null").all} + end + def test_cascaded_eager_association_loading_with_join_for_count categories = Category.joins(:categorizations).includes([{:posts=>:comments}, :authors]) -- 1.7.0.4