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    end

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?              association.save(true)            end

           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            end          end        EOF      end    else      ...    end

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    end

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

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?