Lazy recognition of inheritance hierarchy in STI

Hi –

Given an STI setup like this:

Substitute < Teacher < Person

I get the following, when there’s one Substitute in the database:

Teacher.find(:first)
=> nil
Substitute.find(:first)
=> #<Substitute:0xb7579fec @attributes={“name”=>“David Black”,
“type”=>“Substitute”, “id”=>“1”}>
Teacher.find(:first)
=> #<Substitute:0xb7576be4 @attributes={“name”=>“David Black”,
“type”=>“Substitute”, “id”=>“1”}>

In other words, Teacher is not recognized as a superset of Substitute
at first – but is, after I’ve searched for a Substitute. The
difference, in SQL terms, is:

(people.type = ‘Substitute’ )

vs.

(people.type = ‘Teacher’ OR people.type = ‘Substitute’ )

It seems to me that the inheritance behavior should be one way or the
other, and not change dynamically. Or is there a reason for the
change?

David


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

This happens because the Substitute model had not been loaded at the
time of
the Teacher.find(:first) call. By the time the second call was made, the
Substitute model had been referenced and, therefore, substitute.rb had
been
loaded.

One option would be to explicitly load the substitute model in
teacher.rb:

require_dependency ‘substitute’

-Jonathan.

Hi –

On Sun, 5 Nov 2006, Jonathan V. wrote:

at first – but is, after I’ve searched for a Substitute. The
change?

This happens because the Substitute model had not been loaded at the time of
the Teacher.find(:first) call. By the time the second call was made, the
Substitute model had been referenced and, therefore, substitute.rb had been
loaded.

One option would be to explicitly load the substitute model in teacher.rb:

require_dependency ‘substitute’

Thanks – that does indeed work. I’m just surprised (I guess I never
ran into it before) that there isn’t more eager loading/checking for
subclasses, since the possibility exists that they will be there, and
since it’s acknowledged that Teacher.find(n) can be a Substitute. I
could understand if a decision had been made that Superclass.find(n)
would never include subclasses… but since that’s not the case,
it’s odd to me that it flips from one behavior to the other.

Perhaps I shall write an eager_sti plugin… :slight_smile:

David


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org