Skip to content
This repository
Browse code

Polymorphic join support for has_one associations (has_one :foo, :as …

…=> :bar). Closes #3785.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3558 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
commit b3065a51a927ded6b22835837598e92df606eaed 1 parent c326851
Jeremy Kemper jeremy authored
2  activerecord/CHANGELOG
... ... @@ -1,5 +1,7 @@
1 1 *SVN*
2 2
  3 +* Polymorphic join support for has_one associations (has_one :foo, :as => :bar) #3785 [Rick Olson]
  4 +
3 5 * PostgreSQL: correctly parse negative integer column defaults. #3776 [bellis@deepthought.org]
4 6
5 7 * Fix problems with count when used with :include [Jeremy Hopple and Kevin Clark]
2  activerecord/lib/active_record/associations.rb
@@ -899,7 +899,7 @@ def create_has_many_reflection(association_id, options, &extension)
899 899
900 900 def create_has_one_reflection(association_id, options)
901 901 options.assert_valid_keys(
902   - :class_name, :foreign_key, :remote, :conditions, :order, :include, :dependent, :counter_cache, :extend
  902 + :class_name, :foreign_key, :remote, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as
903 903 )
904 904
905 905 reflection = create_reflection(:has_one, association_id, options, self)
10 activerecord/lib/active_record/associations/has_one_association.rb
@@ -66,9 +66,15 @@ def find_target
66 66 end
67 67
68 68 def construct_sql
69   - @finder_sql = "#{@reflection.table_name}.#{@reflection.primary_key_name} = #{@owner.quoted_id}"
  69 + case
  70 + when @reflection.options[:as]
  71 + @finder_sql =
  72 + "#{@reflection.klass.table_name}.#{@reflection.options[:as]}_id = #{@owner.quoted_id} AND " +
  73 + "#{@reflection.klass.table_name}.#{@reflection.options[:as]}_type = '#{ActiveRecord::Base.send(:class_name_of_active_record_descendant, @owner.class).to_s}'"
  74 + else
  75 + @finder_sql = "#{@reflection.table_name}.#{@reflection.primary_key_name} = #{@owner.quoted_id}"
  76 + end
70 77 @finder_sql << " AND (#{sanitize_sql(@reflection.options[:conditions])})" if @reflection.options[:conditions]
71   - @finder_sql
72 78 end
73 79 end
74 80 end
11 activerecord/test/associations_join_model_test.rb
@@ -26,6 +26,10 @@ def test_inherited_has_many
26 26 def test_polymorphic_has_many
27 27 assert_equal taggings(:welcome_general), posts(:welcome).taggings.first
28 28 end
  29 +
  30 + def test_polymorphic_has_one
  31 + assert_equal taggings(:welcome_general), posts(:welcome).tagging
  32 + end
29 33
30 34 def test_polymorphic_belongs_to
31 35 assert_equal posts(:welcome), posts(:welcome).taggings.first.taggable
@@ -46,7 +50,12 @@ def test_polymorphic_has_many_create_model_with_inheritance
46 50 tagging = tags(:misc).taggings.create(:taggable => post)
47 51 assert_equal "Post", tagging.taggable_type
48 52 end
49   -
  53 +
  54 + def test_polymorphic_has_one_create_model_with_inheritance
  55 + tagging = tags(:misc).create_tagging(:taggable => posts(:thinking))
  56 + assert_equal "Post", tagging.taggable_type
  57 + end
  58 +
50 59 def test_has_many_with_piggyback
51 60 assert_equal "2", categories(:sti_test).authors.first.post_id.to_s
52 61 end
2  activerecord/test/fixtures/post.rb
@@ -23,6 +23,8 @@ def find_most_recent
23 23 has_many :taggings, :as => :taggable
24 24 has_many :tags, :through => :taggings
25 25
  26 + has_one :tagging, :as => :taggable
  27 +
26 28 has_many :categorizations, :foreign_key => :category_id
27 29 has_many :authors, :through => :categorizations
28 30
1  activerecord/test/fixtures/tag.rb
... ... @@ -1,3 +1,4 @@
1 1 class Tag < ActiveRecord::Base
2 2 has_many :taggings, :as => :taggable
  3 + has_one :tagging, :as => :taggable
3 4 end

0 comments on commit b3065a5

Please sign in to comment.
Something went wrong with that request. Please try again.