diff options
author | Rick Olson <technoweenie@gmail.com> | 2006-03-19 03:05:21 +0000 |
---|---|---|
committer | Rick Olson <technoweenie@gmail.com> | 2006-03-19 03:05:21 +0000 |
commit | 9412c0531d53c8070ab0787a00ceb0782736d8d2 (patch) | |
tree | 9b7deadfa9a5ffb5f989ddb905c95009e6ed88d3 | |
parent | 3f77a04cb5244111354b61b97b06ead49a153d29 (diff) | |
download | rails-9412c0531d53c8070ab0787a00ceb0782736d8d2.tar.gz rails-9412c0531d53c8070ab0787a00ceb0782736d8d2.tar.bz2 rails-9412c0531d53c8070ab0787a00ceb0782736d8d2.zip |
Eager Loading support added for has_many :through => :has_many associations (see below). [Rick Olson]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3967 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
-rwxr-xr-x | activerecord/lib/active_record/associations.rb | 18 | ||||
-rw-r--r-- | activerecord/test/associations_join_model_test.rb | 12 |
2 files changed, 24 insertions, 6 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 9d4ba329bc..fb4895433d 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1244,7 +1244,7 @@ module ActiveRecord class JoinAssociation < JoinBase attr_reader :reflection, :parent, :aliased_table_name, :aliased_prefix, :aliased_join_table_name, :parent_table_name - delegate :options, :klass, :to => :reflection + delegate :options, :klass, :through_reflection, :source_reflection, :to => :reflection def initialize(reflection, join_dependency, parent = nil) reflection.check_validity! @@ -1291,7 +1291,6 @@ module ActiveRecord when :has_many, :has_one case when reflection.macro == :has_many && reflection.options[:through] - through_reflection = parent.active_record.reflect_on_association(reflection.options[:through]) through_conditions = through_reflection.options[:conditions] ? "AND #{interpolate_sql(sanitize_sql(through_reflection.options[:conditions]))}" : '' if through_reflection.options[:as] # has_many :through against a polymorphic join polymorphic_foreign_key = through_reflection.options[:as].to_s + '_id' @@ -1305,16 +1304,26 @@ module ActiveRecord " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [table_name_and_alias, aliased_table_name, primary_key, aliased_join_table_name, options[:foreign_key] || reflection.klass.to_s.classify.foreign_key ] - else # has_many :through against a normal join + elsif source_reflection.macro == :belongs_to # has_many :through against a belongs_to " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [ table_alias_for(through_reflection.klass.table_name, aliased_join_table_name), aliased_join_table_name, - through_reflection.options[:foreign_key] || through_reflection.active_record.to_s.classify.foreign_key, + through_reflection.primary_key_name, parent.aliased_table_name, parent.primary_key] + " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [ table_name_and_alias, aliased_table_name, primary_key, aliased_join_table_name, options[:foreign_key] || klass.to_s.classify.foreign_key ] + elsif source_reflection.macro == :has_many # has_many :through against a has_many + " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [ + table_alias_for(through_reflection.klass.table_name, aliased_join_table_name), aliased_join_table_name, + through_reflection.primary_key_name, + parent.aliased_table_name, parent.primary_key] + + " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [ + table_name_and_alias, + aliased_table_name, through_reflection.klass.to_s.classify.foreign_key, + aliased_join_table_name, options[:foreign_key] || primary_key + ] end when reflection.macro == :has_many && reflection.options[:as] @@ -1325,6 +1334,7 @@ module ActiveRecord aliased_table_name, "#{reflection.options[:as]}_type", klass.quote(parent.active_record.base_class.name) ] + else " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [ table_name_and_alias, diff --git a/activerecord/test/associations_join_model_test.rb b/activerecord/test/associations_join_model_test.rb index 4b0f4e4c33..db5f362610 100644 --- a/activerecord/test/associations_join_model_test.rb +++ b/activerecord/test/associations_join_model_test.rb @@ -231,11 +231,11 @@ class AssociationsJoinModelTest < Test::Unit::TestCase end def test_has_many_through_has_many_find_all - assert_equal comments(:greetings), authors(:david).comments.find(:all).first + assert_equal comments(:greetings), authors(:david).comments.find(:all, :order => 'comments.id').first end def test_has_many_through_has_many_find_first - assert_equal comments(:greetings), authors(:david).comments.find(:first) + assert_equal comments(:greetings), authors(:david).comments.find(:first, :order => 'comments.id') end def test_has_many_through_has_many_find_conditions @@ -246,6 +246,14 @@ class AssociationsJoinModelTest < Test::Unit::TestCase assert_equal comments(:more_greetings), authors(:david).comments.find(2) end + def test_eager_load_has_many_through_has_many + author = Author.find :first, :conditions => ['name = ?', 'David'], :include => :comments, :order => 'comments.id' + SpecialComment.new; VerySpecialComment.new + assert_no_queries do + assert_equal [1,2,3,5,6,7,8,9,10], author.comments.collect(&:id) + end + end + private # create dynamic Post models to allow different dependency options def find_post_with_dependency(post_id, association, association_name, dependency) |