# STI subclassing

**URL:** <https://www.ruby-forum.com/t/sti-subclassing/149367>\
**Category:** Rails\
**Created:** [September 24, 2008, 7:54am UTC](https://www.ruby-forum.com/t/sti-subclassing/149367 "2008-09-24T07:54:45Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![magic\_hat](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/5daacb/32.png) [@magic\_hat](https://www.ruby-forum.com/u/magic_hat)\
**Post date:** [September 24, 2008, 7:54am UTC](https://www.ruby-forum.com/t/sti-subclassing/149367/1 "2008-09-24T07:54:45Z")

</div>

Hi, all. I’m wrestling with subclassing models in AR. Wondering if i’m  
running up against a limitation on sub-subclassing, or if the syntax  
has gone awry here.

My app has BlogPosts, which are a sub of Articles. It’s got Writers \<  
RegisteredUsers \< Users.

When I try to call registered\_user on a BlogPost, I get nil.

Any & all help appreciated.

class Article \< ActiveRecord::Base  
etc…

end

class BlogPost \< Article  
validates\_presence\_of :section\_id, :title, :body  
belongs\_to :registered\_user

end

class NewsArticle \< Article  
belongs\_to :writer  
end

require “digest/md5”  
class User \< ActiveRecord::Base  
etc…  
end

class RegisteredUser \< User  
validates\_uniqueness\_of :name  
has\_many :comments  
has\_many :events, :class\_name =\> “Article”, :foreign\_key =\>  
“user\_id”  
has\_many :blog\_posts, :class\_name =\> “Article”, :foreign\_key =\>  
“user\_id”  
end

class Writer \< RegisteredUser  
has\_many :news\_articles, :class\_name =\> “Article”, :foreign\_key =\>  
“user\_id”  
end

> > @post=BlogPost.find(:first, :conditions=\>‘user\_id=1’)  
> > =\> #\<BlogPost id: 505, title: “Cubs outlook”, type: “BlogPost”,  
> > user\_id: 1\>
> 
> > User.find(1)  
> > =\> #\<Writer id: 1, type: “Writer”\>
> 
> > @post.registered\_user  
> > =\> nil

---

<div class="post-metadata">

**Author:** ![magic\_hat](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/5daacb/32.png) [@magic\_hat](https://www.ruby-forum.com/u/magic_hat)\
**Post date:** [September 25, 2008, 3:53am UTC](https://www.ruby-forum.com/t/sti-subclassing/149367/2 "2008-09-25T03:53:46Z")

</div>

That works. Thanks.

One other issue that’s cropping up.

The STI inheiritance has some weird loading behavior. Writers are not  
found with RegisteredUser.find until after they’ve been loaded with  
Writer.find:

> RegisteredUser.find\_by\_name(‘John D.’)  
> =\> nil
> 
> > Writer.find\_by\_name(‘John D.’)  
> > =\> #\<Writer id: 1, name: “John D.”\>  
> > RegisteredUser.find\_by\_name(‘John D.’)  
> > =\> #\<Writer id: 1, name: “John D.”\>

Any idea what that’s all about?

On Sep 24, 7:17 am, Mark Reginald J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![magic\_hat](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/5daacb/32.png) [@magic\_hat](https://www.ruby-forum.com/u/magic_hat)\
**Post date:** [September 24, 2008, 2:18pm UTC](https://www.ruby-forum.com/t/sti-subclassing/149367/3 "2008-09-24T14:18:45Z")

</div>

magic\_hat wrote:

> end  
> has\_many :events, :class\_name =\> “Article”, :foreign\_key =\>
> 
> > > @post=BlogPost.find(:first, :conditions=\>‘user\_id=1’)  
> > > =\> #\<BlogPost id: 505, title: “Cubs outlook”, type: “BlogPost”,  
> > > user\_id: 1\>  
> > > User.find(1)  
> > > =\> #\<Writer id: 1, type: “Writer”\>  
> > > @post.registered\_user  
> > > =\> nil

You should instead have:

belongs\_to :registered\_user, :foreign\_key =\> :user\_id

A Rails bug meant that you didn’t get an error message.

–  
Rails Wheels - Find Plugins, List & Sell Plugins -  
[http://railswheels.com](http://railswheels.com)

---

<div class="post-metadata">

**Author:** ![magic\_hat](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/5daacb/32.png) [@magic\_hat](https://www.ruby-forum.com/u/magic_hat)\
**Post date:** [September 27, 2008, 12:55pm UTC](https://www.ruby-forum.com/t/sti-subclassing/149367/4 "2008-09-27T12:55:25Z")

</div>

magic\_hat wrote:

> Any idea what that’s all about?

Yes, STI subclasses aren’t added to find conditions  
until they’re loaded.

One way to force loading of subclasses is to call  
require\_dependency at the bottom of model files.  
e.g. require\_dependency ‘writer’.

Another way is to name each leaf STI class in  
environment.rb, which forces loading of all classes  
up the tree.

You may have to use method 2 for production mode  
and method 1 for other modes.

There’s also this plugin, which I haven’t yet tried:  
[http://agilewebdevelopment.com/plugins/has\_types](http://agilewebdevelopment.com/plugins/has_types)

–  
Rails Wheels - Find Plugins, List & Sell Plugins -  
[http://railswheels.com](http://railswheels.com)
