From 54fcbb881d1d707d65d38cd30f50049023448832 Mon Sep 17 00:00:00 2001
From: Emilio Tagua <miloops@gmail.com>
Date: Wed, 19 Aug 2009 17:45:13 -0300
Subject: Make sure join association methods are called once.

---
 activerecord/lib/active_record/associations.rb | 19 ++++++++++---------
 activerecord/lib/active_record/base.rb         |  8 ++++----
 2 files changed, 14 insertions(+), 13 deletions(-)

(limited to 'activerecord')

diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 1f1ae93bb6..068943c454 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -2059,6 +2059,7 @@ module ActiveRecord
               @aliased_prefix     = "t#{ join_dependency.joins.size }"
               @parent_table_name  = parent.active_record.table_name
               @aliased_table_name = aliased_table_name_for(table_name)
+              @join               = nil
 
               if reflection.macro == :has_and_belongs_to_many
                 @aliased_join_table_name = aliased_table_name_for(reflection.options[:join_table], "_join")
@@ -2070,9 +2071,9 @@ module ActiveRecord
             end
 
             def association_join
+              return @join if @join
               connection = reflection.active_record.connection
-
-              join = case reflection.macro
+              @join = case reflection.macro
                 when :has_and_belongs_to_many
                   ["%s.%s = %s.%s " % [
                      connection.quote_table_name(aliased_join_table_name),
@@ -2182,14 +2183,14 @@ module ActiveRecord
                 else
                   ""
               end
-              join << %(AND %s) % [
+              @join << %(AND %s) % [
                 klass.send(:type_condition, aliased_table_name)] unless klass.descends_from_active_record?
 
               [through_reflection, reflection].each do |ref|
-                join << "AND #{interpolate_sql(sanitize_sql(ref.options[:conditions], aliased_table_name))} " if ref && ref.options[:conditions]
+                @join << "AND #{interpolate_sql(sanitize_sql(ref.options[:conditions], aliased_table_name))} " if ref && ref.options[:conditions]
               end
 
-              join
+              @join
             end
 
             def relation
@@ -2203,12 +2204,12 @@ module ActiveRecord
             end
 
             def join_relation(joining_relation, join = nil)
-              if relation.is_a?(Array)
+              if (relations = relation).is_a?(Array)
                 joining_relation.
-                  joins(relation.first, Arel::OuterJoin).on(association_join.first).
-                  joins(relation.last, Arel::OuterJoin).on(association_join.last)
+                  joins(relations.first, Arel::OuterJoin).on(association_join.first).
+                  joins(relations.last, Arel::OuterJoin).on(association_join.last)
               else
-                joining_relation.joins(relation, Arel::OuterJoin).on(association_join)
+                joining_relation.joins(relations, Arel::OuterJoin).on(association_join)
               end
             end
 
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index dc439ff92e..b0286f7409 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -1815,11 +1815,11 @@ module ActiveRecord #:nodoc:
           join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(self, joins, nil)
           relation = arel_table.relation
           join_dependency.join_associations.map { |association|
-            if association.relation.is_a?(Array)
-              [Arel::InnerJoin.new(relation, association.relation.first, association.association_join.first).joins(relation),
-              Arel::InnerJoin.new(relation, association.relation.last, association.association_join.last).joins(relation)].join()
+            if (association_relation = association.relation).is_a?(Array)
+              [Arel::InnerJoin.new(relation, association_relation.first, association.association_join.first).joins(relation),
+              Arel::InnerJoin.new(relation, association_relation.last, association.association_join.last).joins(relation)].join()
             else
-              Arel::InnerJoin.new(relation, association.relation, association.association_join).joins(relation)
+              Arel::InnerJoin.new(relation, association_relation, association.association_join).joins(relation)
             end
           }.join(" ")
         end
-- 
cgit v1.2.3