# Is STI the only way to do inheritance?

**URL:** <https://www.ruby-forum.com/t/is-sti-the-only-way-to-do-inheritance/52639>\
**Category:** Rails\
**Created:** [January 17, 2006, 10:20am UTC](https://www.ruby-forum.com/t/is-sti-the-only-way-to-do-inheritance/52639 "2006-01-17T10:20:58Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![terhorst](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b9e5f3/32.png) [@terhorst](https://www.ruby-forum.com/u/terhorst)\
**Post date:** [January 17, 2006, 10:20am UTC](https://www.ruby-forum.com/t/is-sti-the-only-way-to-do-inheritance/52639/1 "2006-01-17T10:20:58Z")

</div>

I’m currently coding a system which must store multiple contact methods  
for  
a user (phone, email, postal address etc). I’m planning a fairly  
straightforward inheritance hierachy for these, where each different  
method  
inherits from something like a ContactMethod class.

The only mention of ActiveRecord support for inheritance I can find in  
the  
Wiki and the Agile Web Dev book is STI. What’s not clear is whether STI  
is  
the _only_ way that this will work. If I define my classes to have  
inheritance relationships and then create a separate table for each  
subclass  
will it not work?

Many thanks.

---

<div class="post-metadata">

**Author:** ![terhorst](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b9e5f3/32.png) [@terhorst](https://www.ruby-forum.com/u/terhorst)\
**Post date:** [January 17, 2006, 11:39am UTC](https://www.ruby-forum.com/t/is-sti-the-only-way-to-do-inheritance/52639/2 "2006-01-17T11:39:09Z")

</div>

On Tue, Jan 17, 2006 at 08:42:51AM -0000, Jonathan T. wrote:

> I’m currently coding a system which must store multiple contact methods for  
> a user (phone, email, postal address etc). I’m planning a fairly  
> straightforward inheritance hierachy for these, where each different method  
> inherits from something like a ContactMethod class.
> 
> The only mention of ActiveRecord support for inheritance I can find in the  
> Wiki and the Agile Web Dev book is STI. What’s not clear is whether STI is  
> the _only_ way that this will work. If I define my classes to have  
> inheritance relationships and then create a separate table for each subclass  
> will it not work?

I tried this over the weekend, thinking that it wouldn’t be huge issue.  
What I had was a fairly simple hierarchy, like this:

```
 User
 / \
/ \

```

Admin Customer

Both Admins and Customers could log in, so the User class has all the  
common  
stuff (login, password changing, etc), but there’s no table for User.

It’s this last part that caused the problem for me. The moment I tried  
to  
run something on the User class (even if the method had been overridden  
by  
me), the User class attempted to access the table users and it all fell  
apart.

I think that if you had a table behind your base class, it _might_ work,  
but  
that seems pretty pointless.

The way I sorted the problem was to create a User class, containing all  
of  
the class methods, and a UserMixin module, for the benefit of the  
“subclasses”. It’s a pity that it needs to be done this way, and I  
fully  
agree that it’s not the most OO way of doing things, but if it becomes a  
common, standard idiom, it won’t be a major problem.

Of course, if we really want to support inheritance, then we want to  
throw  
out this ORM business and go to a real object database…

- Matt

---

<div class="post-metadata">

**Author:** ![terhorst](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b9e5f3/32.png) [@terhorst](https://www.ruby-forum.com/u/terhorst)\
**Post date:** [January 17, 2006, 6:01pm UTC](https://www.ruby-forum.com/t/is-sti-the-only-way-to-do-inheritance/52639/3 "2006-01-17T18:01:18Z")

</div>

Matt, I did the same thing, where you are trying to do STI on 2 out of  
your 3 Models, and I posted here, under ‘subclassing part of STI’, but  
got no response.

Since my example only needed one deviation from the normal Model  
(Telecommunications Room is a subclass of Room), I just added another  
column for boolean to delineate the type.

I’m going to try the links posted, I hope there is some other  
workaround to adding another column, but in the long-run, once you  
create the helper to only return the ‘subclasses’ based on a boolean  
type, you’re going to work with it like any other Model.

- Nic.

On 1/17/06, Matthew P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > will it not work?  
> > stuff (login, password changing, etc), but there’s no table for User.  
> > the class methods, and a UserMixin module, for the benefit of the  
> > removed\_email\_address@domain.invalid  
> > [http://lists.rubyonrails.org/mailman/listinfo/rails](http://lists.rubyonrails.org/mailman/listinfo/rails)

–

- Nic

---

<div class="post-metadata">

**Author:** ![terhorst](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b9e5f3/32.png) [@terhorst](https://www.ruby-forum.com/u/terhorst)\
**Post date:** [January 17, 2006, 11:39pm UTC](https://www.ruby-forum.com/t/is-sti-the-only-way-to-do-inheritance/52639/4 "2006-01-17T23:39:02Z")

</div>

On Tue, Jan 17, 2006 at 08:24:02AM -0800, Nic W. wrote:

> create the helper to only return the ‘subclasses’ based on a boolean  
> type, you’re going to work with it like any other Model.

For subclassing where there is a limited amount of deviance in the data  
fields (and, more importantly, that the semantics of any particular  
field,  
where present across classes, is consistent), I think that STI is a very  
good solution to the interitance problem (unless you’re planning on  
taking  
advantage of PgSQL’s table interitance stuff, which I’ve wanted to look  
at  
for a while now).

In my case, I would have absolutely used STI except that I was mapping  
to a  
legacy database (let’s all sing the song together) and couldn’t make  
major  
schema changes to support this sort of thing.

- Matt

---

<div class="post-metadata">

**Author:** ![terhorst](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b9e5f3/32.png) [@terhorst](https://www.ruby-forum.com/u/terhorst)\
**Post date:** [January 17, 2006, 12:24pm UTC](https://www.ruby-forum.com/t/is-sti-the-only-way-to-do-inheritance/52639/5 "2006-01-17T12:24:14Z")

</div>

On 1/17/06, Jonathan T. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> will it not work?

Rails only support STI, but there are two more methods/patterns:

[http://wiki.rubyonrails.com/rails/pages/SingleTableInheritance](http://wiki.rubyonrails.com/rails/pages/SingleTableInheritance)

You can read the Martin F.'s explanations listed there.  
Here [http://dev.rubyonrails.org/ticket/600](http://dev.rubyonrails.org/ticket/600) you can find a patch for a  
Class  
Table inheritance implementation. If yoy try it, please share your  
experiencie with it here :].

---

<div class="post-metadata">

**Author:** ![terhorst](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b9e5f3/32.png) [@terhorst](https://www.ruby-forum.com/u/terhorst)\
**Post date:** [January 18, 2006, 1:09am UTC](https://www.ruby-forum.com/t/is-sti-the-only-way-to-do-inheritance/52639/6 "2006-01-18T01:09:29Z")

</div>

On 1/17/06, Matthew P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > workaround to adding another column, but in the long-run, once you  
> > In my case, I would have absolutely used STI except that I was mapping to a  
> > legacy database (let’s all sing the song together) and couldn’t make major  
> > schema changes to support this sort of thing.
> 
> - Matt
> 
> * * *
> 
> Rails mailing list  
> removed\_email\_address@domain.invalid  
> [http://lists.rubyonrails.org/mailman/listinfo/rails](http://lists.rubyonrails.org/mailman/listinfo/rails)

IIRC, you can use different tables as long as you  
Model.set\_table\_name. Am I wrong?

–  
Kyle M.  
Chief Technologist  
E Factor Media // FN Interactive  
removed\_email\_address@domain.invalid  
1-866-263-3261

---

<div class="post-metadata">

**Author:** ![terhorst](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b9e5f3/32.png) [@terhorst](https://www.ruby-forum.com/u/terhorst)\
**Post date:** [January 18, 2006, 10:14am UTC](https://www.ruby-forum.com/t/is-sti-the-only-way-to-do-inheritance/52639/7 "2006-01-18T10:14:51Z")

</div>

On 17/01/2006, at 11:47 PM, Rodrigo A. Fernández wrote:

> Rails only support STI, but there are two more methods/patterns:
> 
> [Peak Obsession](http://wiki.rubyonrails.com/rails/pages/SingleTableInheritance)
> 
> You can read the Martin F.'s explanations listed there.  
> Here [http://dev.rubyonrails.org/ticket/600](http://dev.rubyonrails.org/ticket/600) you can find a patch for  
> a Class Table inheritance implementation. If yoy try it, please  
> share your experiencie with it here :].

Oooh, nice, I’ve been planning to write something like this. It  
should converted in to a plugin quite easily. Time for some fun 🙂

–  
Phillip H.  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![terhorst](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b9e5f3/32.png) [@terhorst](https://www.ruby-forum.com/u/terhorst)\
**Post date:** [January 18, 2006, 2:48am UTC](https://www.ruby-forum.com/t/is-sti-the-only-way-to-do-inheritance/52639/8 "2006-01-18T02:48:59Z")

</div>

On Tue, Jan 17, 2006 at 03:31:19PM -0800, Kyle M. wrote:

> > > I’m going to try the links posted, I hope there is some other
> > 
> > In my case, I would have absolutely used STI except that I was mapping to a  
> > legacy database (let’s all sing the song together) and couldn’t make major  
> > schema changes to support this sort of thing.
> 
> IIRC, you can use different tables as long as you  
> Model.set\_table\_name. Am I wrong?

If the class name matches the table appropriately, I don’t think you  
even  
have to do that. The problem comes when you want to use the (common)  
idiom  
of “base class not backed by a table, subclassed to concrete  
(table-backed)  
classes”.

- Matt

---

<div class="post-metadata">

**Author:** ![terhorst](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b9e5f3/32.png) [@terhorst](https://www.ruby-forum.com/u/terhorst)\
**Post date:** [January 18, 2006, 6:54pm UTC](https://www.ruby-forum.com/t/is-sti-the-only-way-to-do-inheritance/52639/9 "2006-01-18T18:54:52Z")

</div>

On 1/17/06, Matthew P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > > 
> > > 
> > > for a while now).  
> > > of “base class not backed by a table, subclassed to concrete (table-backed)  
> > > classes”.

You’re right, and I tried this out to confirm it. I left out a bit of  
my explanation for clarity, but my ultimate goal was to be able to use  
that same ‘type’ column as a descriptor, but then on certain ‘types’  
I could subclass it.

So, Telecommunications Room would be subclassed, but not Office. The  
use case for this being that I could display the type of room, but if  
it was a Telecommunications Room, display more information.

This is what I can’t seem to get RoR to support, but from others help  
and such, it isn’t possible w/o another column. It goes back to  
AbstractModel I think.

- Nic.

> * * *
> 
> Rails mailing list  
> removed\_email\_address@domain.invalid  
> [http://lists.rubyonrails.org/mailman/listinfo/rails](http://lists.rubyonrails.org/mailman/listinfo/rails)

–

- Nic
