aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/CHANGELOG8
-rwxr-xr-xactiverecord/lib/active_record/associations.rb16
-rw-r--r--activerecord/test/associations_join_model_test.rb16
-rw-r--r--activerecord/test/fixtures/tag.rb4
4 files changed, 36 insertions, 8 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index dc61ab3c31..bd06810c36 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,13 @@
*SVN*
+* Added support for eagerly including polymorphic has_one associations. (closes #4525) [Rick]
+
+ class Post < ActiveRecord::Base
+ has_one :tagging, :as => :taggable
+ end
+
+ Post.find :all, :include => :tagging
+
* Added descriptive error messages for invalid has_many :through associations: going through :has_one or :has_and_belongs_to_many [Rick]
* Added support for going through a polymorphic has_many association: (closes #4401) [Rick]
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 5319fa39e8..7b6257ec03 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1392,7 +1392,7 @@ module ActiveRecord
@aliased_prefix = "t#{ join_dependency.joins.size }"
@aliased_table_name = table_name # start with the table name
@parent_table_name = parent.active_record.table_name
-
+
if !parent.table_joins.blank? && parent.table_joins.to_s.downcase =~ %r{join(\s+\w+)?\s+#{aliased_table_name.downcase}\son}
join_dependency.table_aliases[aliased_table_name] += 1
end
@@ -1473,12 +1473,16 @@ module ActiveRecord
aliased_table_name, "#{reflection.options[:as]}_type",
klass.quote(parent.active_record.base_class.name)
]
-
+ when reflection.macro == :has_one && reflection.options[:as]
+ " LEFT OUTER JOIN %s ON %s.%s = %s.%s AND %s.%s = %s " % [
+ table_name_and_alias,
+ aliased_table_name, "#{reflection.options[:as]}_id",
+ parent.aliased_table_name, parent.primary_key,
+ aliased_table_name, "#{reflection.options[:as]}_type",
+ klass.quote(reflection.active_record.name)
+ ]
else
- foreign_key = options[:foreign_key] || case reflection.macro
- when :has_many then reflection.active_record.to_s.classify
- when :has_one then reflection.active_record.to_s
- end.foreign_key
+ foreign_key = options[:foreign_key] || reflection.active_record.name.foreign_key
" LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [
table_name_and_alias,
aliased_table_name, foreign_key,
diff --git a/activerecord/test/associations_join_model_test.rb b/activerecord/test/associations_join_model_test.rb
index b7f0af173b..4a11d4c5eb 100644
--- a/activerecord/test/associations_join_model_test.rb
+++ b/activerecord/test/associations_join_model_test.rb
@@ -208,6 +208,14 @@ class AssociationsJoinModelTest < Test::Unit::TestCase
end
end
+ def test_include_polymorphic_has_one
+ post = Post.find_by_id(posts(:welcome).id, :include => :tagging)
+ tagging = taggings(:welcome_general)
+ assert_no_queries do
+ assert_equal tagging, post.tagging
+ end
+ end
+
def test_include_polymorphic_has_many_through
posts = Post.find(:all, :order => 'posts.id')
posts_with_tags = Post.find(:all, :include => :tags, :order => 'posts.id')
@@ -303,6 +311,14 @@ class AssociationsJoinModelTest < Test::Unit::TestCase
assert_equal [taggings(:welcome_general), taggings(:thinking_general)], authors(:david).taggings.uniq.sort_by { |t| t.id }
end
+ def test_has_many_through_polymorphic_has_many_with_eager_loading
+ author = Author.find_by_id(authors(:david).id, :include => :taggings)
+ expected_taggings = [taggings(:welcome_general), taggings(:thinking_general)]
+ assert_no_queries do
+ assert_equal expected_taggings, author.taggings.uniq.sort_by { |t| t.id }
+ end
+ end
+
def test_has_many_through_has_many_through
assert_raise(ActiveRecord::HasManyThroughSourceAssociationMacroError) { authors(:david).tags }
end
diff --git a/activerecord/test/fixtures/tag.rb b/activerecord/test/fixtures/tag.rb
index ed3c6ce34a..c12ec0c188 100644
--- a/activerecord/test/fixtures/tag.rb
+++ b/activerecord/test/fixtures/tag.rb
@@ -1,5 +1,5 @@
class Tag < ActiveRecord::Base
- has_many :taggings, :as => :taggable
+ has_many :taggings
has_many :taggables, :through => :taggings
- has_one :tagging, :as => :taggable
+ has_one :tagging
end \ No newline at end of file