# Any good alternative to single-table-inheritance?

**URL:** <https://www.ruby-forum.com/t/any-good-alternative-to-single-table-inheritance/99140>\
**Category:** Rails\
**Created:** [July 20, 2006, 4:10pm UTC](https://www.ruby-forum.com/t/any-good-alternative-to-single-table-inheritance/99140 "2006-07-20T16:10:23Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [July 20, 2006, 4:10pm UTC](https://www.ruby-forum.com/t/any-good-alternative-to-single-table-inheritance/99140/1 "2006-07-20T16:10:23Z")

</div>

I’m looking to implement model inheritance in a new application. Is  
there any good alternative to single-table-inheritance?

---

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [July 20, 2006, 4:58pm UTC](https://www.ruby-forum.com/t/any-good-alternative-to-single-table-inheritance/99140/2 "2006-07-20T16:58:34Z")

</div>

On 7/21/06, Alder G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I’m looking to implement model inheritance in a new application. Is  
> there any good alternative to single-table-inheritance?
> 
> –  
> -Alder
> 
> * * *
> 
> Rails mailing list  
> removed\_email\_address@domain.invalid  
> [http://lists.rubyonrails.org/mailman/listinfo/rails](http://lists.rubyonrails.org/mailman/listinfo/rails)

There was a new plugin released recently. I havn’t had a good look at  
it  
but it certainly is an alternative

[http://www.agilewebdevelopment.com/plugins/inherits\_from](http://www.agilewebdevelopment.com/plugins/inherits_from)

---

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [July 20, 2006, 5:58pm UTC](https://www.ruby-forum.com/t/any-good-alternative-to-single-table-inheritance/99140/3 "2006-07-20T17:58:12Z")

</div>

On Thursday, July 20, 2006, at 5:06 PM, Alder G. wrote:

> I’m looking to implement model inheritance in a new application. Is  
> there any good alternative to single-table-inheritance?
> 
> –  
> -Alder
> 
> * * *
> 
> Rails mailing list  
> removed\_email\_address@domain.invalid  
> [http://lists.rubyonrails.org/mailman/listinfo/rails](http://lists.rubyonrails.org/mailman/listinfo/rails)

Why do you want an alternative?

\_Kevin  
[www.sciwerks.com](http://www.sciwerks.com)

---

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [July 20, 2006, 6:38pm UTC](https://www.ruby-forum.com/t/any-good-alternative-to-single-table-inheritance/99140/4 "2006-07-20T18:38:58Z")

</div>

Kevin O. wrote:

> Why do you want an alternative?
> 
> \_Kevin  
> [www.sciwerks.com](http://www.sciwerks.com)

Mmmm I do. I’ll explain why. As RoR learning project I decided to try  
reproducing the core funcionality of an internal CMS-like tool at my  
org. The database already followed most rails-friendly conversions, so  
starting was a breeze. But here’s the problem:  
I have in there “resources”, which can be links, various documents and  
archives, quizzes, forums and on and on for almost 20 types of resource.  
There is a resources table which holds the common columns for all  
resources, then one table for each resource type, and some have in  
excess of 20 columns specific for that type of resource.  
If I have to mashup those into a single STI table i’ll end up with a  
table having between 300 and 400 columns, which I think everyone would  
agree it’s a bad thing.

The alternative? Resource have a belongs\_to polymorphic relation to all  
20 different resource models, which each have a has\_one dependent  
relationship back to the Resource model. This allows me to keep separate  
tables, and somehow keep everything working. The problem? My code isn’t  
making use of inheritance, as I can’t say:  
class Link \< Resource

and have to keep using my aggregation cludge and doing ugly stuff like:

link.resource.name

And I have to always remember deleting links and not resources, as the  
dependence for deleting goes only one way.

Real support for some kind of class table inheritance would make all  
this moot, but I’ve been looking into ActiveRecord and can’t see it  
working as a simple plugin. Adding the functionality would stomp out all  
the simplicity from most of the current code. Doing away with the Just  
One Table per Model principle isn’t the ActiveRecord way.

So I’m just stuck with my project, as I have to choose between an  
inacceptably ugly database or non-OO ugly code, and I chose Rails to  
flee all the uglyness that was there before.

---

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [July 20, 2006, 6:33pm UTC](https://www.ruby-forum.com/t/any-good-alternative-to-single-table-inheritance/99140/5 "2006-07-20T18:33:47Z")

</div>

On 20 Jul 2006 15:57:47 -0000, Kevin O.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > [http://lists.rubyonrails.org/mailman/listinfo/rails](http://lists.rubyonrails.org/mailman/listinfo/rails)
> 
> Why do you want an alternative?

I have a parent model class Foo, and two subclasses Bar and Baz.

The thing is that Bar and Baz are very different. They share 4  
attributes from Foo and an additional common attribute among  
themselves, but also each have 6-7 attributes that are non-shared.

So if I implement this inheritance model with STI, I end up with a  
pretty large table (~20 columns), of which each model uses not more  
than half (and Foo instances use only a fifth).

This looks very non-optimal, and is likely to get worse down the road,  
since Foo is expecting several additional children, each of whom would  
add about 6+ more non-shared attributes. I’d soon end up with a 50+  
column table for producing pretty simple (10 attribute) model  
instances. Much unnecessary complexity.

Looks like the plugin linked by Daniel would prevent that, I’d have a  
look at is (thanks Daniel!)

---

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [July 20, 2006, 6:57pm UTC](https://www.ruby-forum.com/t/any-good-alternative-to-single-table-inheritance/99140/6 "2006-07-20T18:57:21Z")

</div>

Juan Felipe G. wrote:

> The alternative? Resource have a belongs\_to polymorphic relation to all  
> 20 different resource models, which each have a has\_one dependent  
> relationship back to the Resource model. This allows me to keep separate  
> tables, and somehow keep everything working. The problem? My code isn’t  
> making use of inheritance, as I can’t say:  
> class Link \< Resource
> 
> and have to keep using my aggregation cludge and doing ugly stuff like:
> 
> link.resource.name
> 
> And I have to always remember deleting links and not resources, as the  
> dependence for deleting goes only one way.
> 
> Real support for some kind of class table inheritance would make all  
> this moot, but I’ve been looking into ActiveRecord and can’t see it  
> working as a simple plugin. Adding the functionality would stomp out all  
> the simplicity from most of the current code. Doing away with the Just  
> One Table per Model principle isn’t the ActiveRecord way.
> 
> So I’m just stuck with my project, as I have to choose between an  
> inacceptably ugly database or non-OO ugly code, and I chose Rails to  
> flee all the uglyness that was there before.

Yes, I agree with your sentiments. But Ruby has enough mojo to make the  
pain bearable. You can create a mixin module to share behavior in your  
models, and you can use delegation or a method\_missing hack to make the  
explicit message forwarding go away. The polymorphic belongs\_to  
assocations are still kinda ugly, but at least your code doesn’t have to  
be ugly.

–  
Josh S.  
[http://blog.hasmanythrough.com](http://blog.hasmanythrough.com)

---

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [July 20, 2006, 7:22pm UTC](https://www.ruby-forum.com/t/any-good-alternative-to-single-table-inheritance/99140/7 "2006-07-20T19:22:54Z")

</div>

So as it seems to be the current best alternative, I’ll post some of my  
model stuff as a hint:

#The “parent” model for all resources, resources are listed in sections  
#the database table needs “instance\_id” and “instance\_type” columns  
class Resource \< ActiveRecord::Base  
belongs\_to :section  
belongs\_to :instance, :polymorphic =\> :true  
end

#A Link is one type of resource, so every link is the

# “instance” of a resource

class Link \< ActiveRecord::Base  
include ResProperties  
has\_one :resource, :as =\> :instance, :dependent =\> :destroy  
end

#A Lesson is one type of resource, so every lesson is the

# “instance” of a resource

class Lesson \< ActiveRecord::Base  
include ResProperties  
has\_one :resource, :as =\> :instance, :dependent =\> :destroy  
end

… and on and on for 18 more children models

#In this module I put stuff every “child” should have inherited,  
#for example, every resource of any type has a name, which lives in the  
#resources table  
module ResProperties  
def name  
resource.name  
end  
end

Beware the possibility of orphan children. Deleting a link or lesson or  
whatever will take care automagically of the corresponding resource.  
Deleting a resource will leave the corresponding “instance” there  
forever.

I guess some ruby magic in the ResProperties module would go a long way,  
as Josh suggested, I have to read deeper into my new and fresh pickaxe  
copy.

BTW…I’m quite happy about having the has\_many :though guru agreeing  
with my sentiments about such matters, does wonders for my newbie pride  
😉

---

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [July 20, 2006, 7:43pm UTC](https://www.ruby-forum.com/t/any-good-alternative-to-single-table-inheritance/99140/8 "2006-07-20T19:43:15Z")

</div>

On 7/20/06, Juan Felipe G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I have in there “resources”, which can be links, various documents and  
> archives, quizzes, forums and on and on for almost 20 types of resource.  
> There is a resources table which holds the common columns for all  
> resources, then one table for each resource type, and some have in  
> excess of 20 columns specific for that type of resource.  
> If I have to mashup those into a single STI table i’ll end up with a  
> table having between 300 and 400 columns, which I think everyone would  
> agree it’s a bad thing.

Yup, my reason for looking for an alternative is pretty much the same.

> The alternative? Resource have a belongs\_to polymorphic relation to all  
> 20 different resource models, which each have a has\_one dependent  
> relationship back to the Resource model. This allows me to keep separate  
> tables, and somehow keep everything working. The problem? My code isn’t  
> making use of inheritance, as I can’t say:  
> class Link \< Resource
> 
> and have to keep using my aggregation cludge and doing ugly stuff like:
> 
> link.resource.name

As Josh already hinted, you can easily (e.g. through #method\_missing)  
have unanswered methond calls on link routed to link.resource.

You can also meta-programmatically generate the boiler-plate code for  
the 18 children models you mentioned. I would so do that if I were  
you.

Ultimately, as far as the code layer is concerned, Josh is right:  
Ruby’s meta-programming can make the pain go away.

However, as I invariably end up at some point or other dealing  
directly with the database on all long-running project, I’d hesitate  
to create 50+ tables which aren’t essentially necessary for ~10  
attribute models.

Also, when tables might reach 400+ columns such as in your case (and  
in the long run definitely possible on mine), I’d start worrying about  
stuff like performance (e.g. select \* would have to return 400 columns  
per record… brrr) and even (_gasp_) space. Depending on the  
databasse, 400 columns might really hurt when you’re doing a million  
inserts a day.

---

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [July 20, 2006, 7:53pm UTC](https://www.ruby-forum.com/t/any-good-alternative-to-single-table-inheritance/99140/9 "2006-07-20T19:53:27Z")

</div>

If I was 20 yrs. old punk once again I would have already wrote  
something like:

class HyperActiveRecord \< ActiveRecord::Base

And go on overriding the columns, attributes, find, update, insert,…  
methods with the sql join mojo necessary to have proper model  
inheritance… But I’m too old and lazy by now. Instead my project is  
stopped while I ponder about easier options.

Anyone trying, feel free to pick up my class name, I like it a lot 🙂

---

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [July 20, 2006, 7:33pm UTC](https://www.ruby-forum.com/t/any-good-alternative-to-single-table-inheritance/99140/10 "2006-07-20T19:33:53Z")

</div>

On 7/20/06, Juan Felipe G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> #A Link is one type of resource, so every link is the  
> has\_one :resource, :as =\> :instance, :dependent =\> :destroy  
> resource.name  
> end  
> end

That’s the method recommended by DHH on AWDWR. Except he suggests to  
call the pseudo-baseclass something like ResourceMetadata.

It’s in the section about Single Table Inheritance, I was just  
wondering whether a new “best practice” sprung up more recently, since  
frankly this one isn’t perfect.

---

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [April 6, 2007, 1:24am UTC](https://www.ruby-forum.com/t/any-good-alternative-to-single-table-inheritance/99140/11 "2007-04-06T01:24:37Z")

</div>

The are a few solutions if you do a google ‘rails single table  
inheritance’ but none are 100%, for example some functionality is lost  
such as associated join along the chain of inheritance or they are db  
specific such as Postgres table inheritance.

I started by using polymorphic joins to a common model but the code is  
kinda odd, it would be great if the Rails core had STI implemented…  
Does anyone know of any progress in this area?

---

<div class="post-metadata">

**Author:** ![alder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a4c791/32.png) [@alder](https://www.ruby-forum.com/u/alder)\
**Post date:** [July 20, 2006, 8:43pm UTC](https://www.ruby-forum.com/t/any-good-alternative-to-single-table-inheritance/99140/12 "2006-07-20T20:43:13Z")

</div>

On 7/20/06, Juan Felipe G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> If I was 20 yrs. old punk once again I would have already wrote  
> something like:
> 
> class HyperActiveRecord \< ActiveRecord::Base
> 
> And go on overriding the columns, attributes, find, update, insert,…  
> methods with the sql join mojo necessary to have proper model  
> inheritance… But I’m too old and lazy by now. Instead my project is  
> stopped while I ponder about easier options.

Don’t brood over this too much; either go with the AWDWR best practice  
(the minor problems you saw in it are solveable, and you end up with  
something that’s not really kludgy in any way) or have a look at the  
plugin.

Either way, in several months you’ll be such a Rails whiz you’d be  
able to switch MOs in less time than you’ll take “pondering your  
options” right now 😉
