Is STI the only way to do inheritance?


#1

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.


#2

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

#3

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 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

  • Nic

#4

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

#5

On 1/17/06, Jonathan T. 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

You can read the Martin F.'s explanations listed there.
Here 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 :].


#6

On 1/17/06, Matthew P. 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

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


#7

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

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

http://wiki.rubyonrails.com/rails/pages/SingleTableInheritance

You can read the Martin F.'s explanations listed there.
Here 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 :slight_smile:


Phillip H.
removed_email_address@domain.invalid


#8

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

#9

On 1/17/06, Matthew P. 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

  • Nic