Expected behaviour of polymorphic has_many relationship


I posted something similar to this on the Rails-takl list but I've just discovered the core list and Iguess this is a better place to ask. I've been doing a bit of work on inheritance in ActiveRecord and my changes broke this test from associations/join_model_test.rb:

   def test_polymorphic_has_many_create_model_with_inheritance_and_custom_base_class
     post = SubStiPost.create :title => 'SubStiPost', :body => 'SubStiPost body'
     assert_instance_of SubStiPost, post

     tagging = tags(:misc).taggings.create(:taggable => post)
     assert_equal "SubStiPost", tagging.taggable_type

I was getting '<"SubStiPost"> expected but was <"Post">'. To fix this I modified a line in this section of the belongs_to method in associations.rb:

   if reflection.options[:polymorphic]
     association_accessor_methods(reflection, BelongsToPolymorphicAssociation)

     module_eval do
       before_save <<-EOF
         association = instance_variable_get("@#{reflection.name}")
         if association && association.target
           if association.new_record?

           if association.updated?
             self["#{reflection.primary_key_name}"] = association.id
   - self["#{reflection.options[:foreign_type]}"] = association.class.base_class.name.to_s
   + self["#{reflection.options[:foreign_type]}"] = association.class.name.to_s

But that change breaks these tests:

   def test_polymorphic_has_many_create_model_with_inheritance
     post = posts(:thinking)
     assert_instance_of SpecialPost, post

     tagging = tags(:misc).taggings.create(:taggable => post)
     assert_equal "Post", tagging.taggable_type

   def test_polymorphic_has_one_create_model_with_inheritance
     tagging = tags(:misc).create_tagging(:taggable => posts(:thinking))
     assert_equal "Post", tagging.taggable_type

Both now fail on <"Post"> expected but was <"SpecialPost">.

What I don't understand is that the fixture Post :thinking is actually a SpecialPost, so why is that not the correct taggable_type value? I can't figure out what the intended behaviour of this association.

I'd be really grateful for an explanation of this, it's the only thing I can't make work.


What are your original changes, that broke the tests initially?


Hi Evan

It was my attempt at class-table inheritance here: http://dev.rubyonrails.org/ticket/6566

It's not finished yet, because I haven't made it work with associations, but the ONLY thing it breaks in the existing tests (ie if you use a CTI-enabled ActiveRecord but don't actually use CTI) is polymorphic has_many relationships. I think this is because I've redefined the meaning of "abstract class".

Any ideas?