Why must I save/reload to get grandchildren in STI?

I have the following models:

Person < ActiveRecord::Base
end

Contact < Person
belongs_to :company
end

Primarycontact < Contact
belongs_to :company
end

Company < ActiveRecord::Base
has_many :contacts
has_one :primarycontact
end

I have already saved these objects in the database, verified in mysql
client:
(pseudocode)

a => company
joe => primarycontact

When I try to access them this way:

joe.name => ‘joe’ #yep, that’s right
a.primarycontact => joe #good, that’s what I expect
a.contacts.each {|c| puts c.name} => nil #why?
a.save => true
a.contacts(:reload => true).each {|c| puts c.name} => ‘joe’ #huh?

Now I can shut down the console, start it up again, and do the whole
dance again from the top. Why to I have to save / reload every time I
want to get at grandchildren? It’s not as though I’m actually altering
the data in the database. It seems very inefficient.

Any ideas or help you may have would be greatly appreciated.

Thanks,
Eric

I found the solution.

By adding model declarations in application.rb, rails became aware of
the grandchild class Primarycontact from the start, and everything
works fine. ( e.g. model :primarycontact )

My little save /reload dance just tipped rails off that the class
existed so that it could load it’s definition. Explicitly loading the
definition in application.rb solves the problem.

Eric ïèøåò:

I found the solution.

By adding model declarations in application.rb, rails became aware of
the grandchild class Primarycontact from the start, and everything
works fine. ( e.g. model :primarycontact )

My little save /reload dance just tipped rails off that the class
existed so that it could load it’s definition. Explicitly loading the
definition in application.rb solves the problem.

Yeah, that’s the problem with STI in development environment. On every
request all reloadable classes are removed and loaded only on demand. So
STI children and grandchildren could not be loaded on next request.
Maybe, explicitly loading all models would solve this:

app/controllers/application.rb
Dir[RAILS_ROOT+’/app/models/*.rb’].each { |f| require f }