# OO model style: inheritance

**URL:** <https://www.ruby-forum.com/t/oo-model-style-inheritance/50977>\
**Category:** Rails\
**Created:** [December 23, 2005, 11:39am UTC](https://www.ruby-forum.com/t/oo-model-style-inheritance/50977 "2005-12-23T11:39:28Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Luca\_Marinucci](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/f08c70/32.png) [@Luca\_Marinucci](https://www.ruby-forum.com/u/Luca_Marinucci)\
**Post date:** [December 23, 2005, 11:39am UTC](https://www.ruby-forum.com/t/oo-model-style-inheritance/50977/1 "2005-12-23T11:39:28Z")

</div>

Hi everybody

I am totally new to rails and I am trying to start a  
tiny project to get familiar with rails. But I already  
got my first problem and I would be happy if somebody  
could point me in the best and cleanest direction.

I am trying to develop a small gallery app. Since I  
would like to add more features in future I am trying  
to design a clean OO architecture of my models:

The base object should be NODE. All other objects  
extend NODE, those are GALLERY and IMAGE (a GALLERY  
consists of 0…\* IMAGEs). Each NODE has an owner  
(user\_id) plus some default fields like created\_on and  
updated\_on. Futhermore there is an object COMMENT  
which can be attached to any object that extends NODE  
(belongs\_to NODE).

According to this design I modeled the db schema as  
follows:

CREATE TABLE `nodes` (  
`id` int(11) NOT NULL auto\_increment,  
`user_id` int(11) NOT NULL default ‘0’,  
`created_on` timestamp NOT NULL default  
CURRENT\_TIMESTAMP on update CURRENT\_TIMESTAMP,  
`updated_on` timestamp NOT NULL default ‘0000-00-00  
00:00:00’, PRIMARY KEY (`id`)  
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

DROP TABLE IF EXISTS `galleries`;  
CREATE TABLE `galleries` (  
`id` int(11) NOT NULL auto\_increment,  
`node_id` int(11) NOT NULL default ‘0’,  
`user_id` int(11) NOT NULL default ‘0’,  
`title` varchar(255) NOT NULL default ‘’,  
`descr` text NOT NULL,  
PRIMARY KEY (`id`),  
KEY `user_key` (`user_id`),  
KEY `node_key` (`node_id`)  
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

DROP TABLE IF EXISTS `images`;  
CREATE TABLE `images` (  
`id` int(11) NOT NULL auto\_increment,  
`user_id` int(11) NOT NULL default ‘0’,  
`gallery_id` int(11) NOT NULL default ‘0’,  
`node_id` int(11) NOT NULL default ‘0’,  
`title` varchar(255) NOT NULL default ‘’,  
`descr` text NOT NULL,  
PRIMARY KEY (`id`),  
KEY `gallery_key` (`gallery_id`),  
KEY `node_key` (`node_id`),  
KEY `user_key` (`user_id`)  
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `comments` (  
`id` int(11) NOT NULL default ‘0’,  
`node_id` int(11) NOT NULL default ‘0’,  
`user_id` int(11) NOT NULL default ‘0’,  
`title` varchar(255) NOT NULL default ‘’,  
`body` text NOT NULL,  
`created_on` timestamp NOT NULL default  
CURRENT\_TIMESTAMP on update CURRENT\_TIMESTAMP,  
`updated_on` timestamp NOT NULL default ‘0000-00-00  
00:00:00’,  
PRIMARY KEY (`id`),  
KEY `user_key` (`user_id`),  
KEY `node_key` (`node_id`)  
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `users` (  
`id` int(11) NOT NULL auto\_increment,  
`created_on` timestamp NOT NULL default  
CURRENT\_TIMESTAMP on update CURRENT\_TIMESTAMP,

```
      `updated_on` timestamp NOT NULL default

```

‘0000-00-00 00:00:00’,  
`nickname` varchar(255) NOT NULL default ‘’,  
`firstname` varchar(255) NOT NULL default ‘’,  
`lastname` varchar(255) NOT NULL default ‘’,  
`email` varchar(255) NOT NULL default ‘’,  
`passwd` varchar(100) NOT NULL default ‘’,  
PRIMARY KEY (`id`)  
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

My question now is, is this a nice design and is this  
easy to implement with rails? And how should I  
implement my models in rails, should I use inheritance  
or make sure that each NODE extensions sets the  
correct data in the NODE table?

Regards, Luca

* * *

Telefonate ohne weitere Kosten vom PC zum PC: [http://messenger.yahoo.de](http://messenger.yahoo.de)

---

<div class="post-metadata">

**Author:** ![Luca\_Marinucci](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/f08c70/32.png) [@Luca\_Marinucci](https://www.ruby-forum.com/u/Luca_Marinucci)\
**Post date:** [December 23, 2005, 12:09pm UTC](https://www.ruby-forum.com/t/oo-model-style-inheritance/50977/2 "2005-12-23T12:09:32Z")

</div>

Luca,

what is the motivation for your universal Node association? I believe  
it may not be neccessary. For example, the user\_id column is currently  
included in Node as well as each of the models associated with Node.  
Also, fields like created\_on/updated\_on are pretty integral to each  
model, so unless you’re designing an elaborate metadata storage  
engine, I’d leave them right in the model they describe.

You might consider dropping your Node class, and distributing its  
columns amongt the models as needed. For example, if a gallery owner  
also owns all images in the gallery, you wouldn’t need the user\_id  
field in the images table, as it would be available by association.  
Keep it simple, and Rails will be your friend 🙂

Use InnoDB not MyISAM, or else you won’t get to use transactional  
tests. I ran into that tree recently 🙂

cheers  
Gerret

---

<div class="post-metadata">

**Author:** ![Luca\_Marinucci](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/f08c70/32.png) [@Luca\_Marinucci](https://www.ruby-forum.com/u/Luca_Marinucci)\
**Post date:** [December 23, 2005, 12:00pm UTC](https://www.ruby-forum.com/t/oo-model-style-inheritance/50977/3 "2005-12-23T12:00:29Z")

</div>

Rails (or more specifically ActiveRecord) is based on a single table  
per inheritance tree model. So all your Node subclasses will be  
persisted in the NODE table. You should also add a ‘type’ column in  
this table so that ActiveRecord can track what is the type of  
persisted instances.

Cheers,

Matthieu R…

> Hi everybodyI am totally new to rails and I am trying to start atiny  
> project to get familiar with rails. But I alreadygot my first problem  
> and I would be happy if somebodycould point me in the best and  
> cleanest direction.I am trying to develop a small gallery app. Since  
> Iwould like to add more features in future I am tryingto design a  
> clean OO architecture of my models:The base object should be NODE. All  
> other objectsextend NODE, those are GALLERY and IMAGE (a  
> GALLERYconsists of 0…\* IMAGEs). Each NODE has an owner(user\_id) plus  
> some default fields like created\_on andupdated\_on. Futhermore there is  
> an object COMMENTwhich can be attached to any object that extends  
> NODE(belongs\_to NODE).According to this design I modeled the db schema  
> asfollows:CREATE TABLE `nodes` ( `id` int(11) NOT NULL  
> auto\_increment, `user_id` int(11) NOT NULL default ‘0’, `created_on`  
> timestamp NOT NULL defaultCURRENT\_TIMESTAMP on update  
> CURRENT\_TIMESTAMP, `updated_on` timestamp NOT NULL default  
> ‘0000-00-0000:00:00’, PRIMARY KEY (`id`))  
> ENGINEu003dMyISAM DEFAULT CHARSETu003dlatin1;DROP TABLE IF EXISTS  
> `galleries`;CREATE TABLE `galleries` ( `id` int(11) NOT NULL  
> auto\_increment, `node_id` int(11) NOT NULL default ‘0’, `user_id`  
> int(11) NOT NULL default ‘0’, `title` varchar(255) NOT NULL default  
> ‘’, `descr` text NOT NULL, PRIMARY KEY (`id`), KEY `user_key`  
> (`user_id`), KEY `node_key` (`node_id`)) ENGINEu003dMyISAM DEFAULT  
> CHARSETu003dlatin1;DROP TABLE IF EXISTS `images`;CREATE TABLE `images`  
> ( `id` int(11) NOT NULL auto\_increment, `user_id` int(11) NOT NULL  
> default ‘0’, `gallery_id` int(11) NOT NULL default ‘0’, `node_id`  
> int(11) NOT NULL default ‘0’, `title` varchar(255) NOT NULL default  
> ‘’, `descr` text NOT NULL, PRIMARY KEY (`id`), KEY `gallery_key`  
> (`gallery_id`), KEY `node_key` (`node_id`), KEY `user_key`  
> (`user_id`)) ENGINEu003dMyISAM DEFAULT CHARSETu003dlatin1;CREATE TABLE  
> `comments` ( `id` int(11) NOT NULL default ‘0’, `node_id` int(11)  
> NOT NULL default ‘0’, `user_id` int(11) NOT NULL default ‘0’,  
> `title` varchar(255) NOT NULL default ‘’, `body` text NOT NULL,  
> `created_on` timestamp NOT NULL defaultCURRENT\_TIMESTAMP on update  
> CURRENT\_TIMESTAMP, `updated_on` timestamp NOT NULL default  
> ‘0000-00-0000:00:00’, PRIMARY KEY (`id`), KEY `user_key`  
> (`user_id`), KEY `node_key` (`node_id`)) ENGINEu003dMyISAM DEFAULT  
> CHARSETu003dlatin1;CREATE TABLE `users` ( `id` int(11) NOT NULL  
> auto\_increment, `created_on` timestamp NOT NULL  
> defaultCURRENT\_TIMESTAMP on update CURRENT\_TIMESTAMP,  
> `updated_on` timestamp NOT NULL default’0000-00-00 00:00:00’,  
> `nickname` varchar(255) NOT NULL default ‘’, `firstname` varchar(255)  
> NOT NULL default ‘’, `lastname` varchar(255) NOT NULL default ‘’,  
> `email` varchar(255) NOT NULL default ‘’, `passwd` varchar(100) NOT  
> NULL default ‘’, PRIMARY KEY (`id`)) ENGINEu003dMyISAM DEFAULT  
> CHARSETu003dlatin1;My question now is, is this a nice design and is  
> thiseasy to implement with rails? And how should Iimplement my models  
> in rails, should I use inheritanceor make sure that each NODE  
> extensions sets thecorrect data in the NODE table?Regards,  
> Luca\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_Telefonate  
> ohne weitere Kosten vom PC zum PC:  
> http://messenger.yahoo.de\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_Rails  
> mailing  
> removed\_email\_address@domain.invalid://lists.rubyonrails.org/mailman/listinfo/rails

---

<div class="post-metadata">

**Author:** ![Luca\_Marinucci](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/f08c70/32.png) [@Luca\_Marinucci](https://www.ruby-forum.com/u/Luca_Marinucci)\
**Post date:** [December 23, 2005, 1:55pm UTC](https://www.ruby-forum.com/t/oo-model-style-inheritance/50977/4 "2005-12-23T13:55:08Z")

</div>

Hi Gerret

First, thx for your quick response!

> what is the motivation for your universal Node  
> association?

The motivation is to have an extendable content model,  
so that I can easily add new content types such as  
articles or documents in future. Following this  
approach it will be for example possible to allow to  
add comments to all kind of content types. But you are  
right, the user\_id field should be removed from both  
tables, GALLERIES and IMAGES.

> Use InnoDB not MyISAM, or else you won’t get to use  
> transactional tests. I ran into that tree recently  
> 🙂

Ah great, thx for the hint!

Luca

> > could point me in the best and cleanest direction.  
> > consists of 0…\* IMAGEs). Each NODE has an owner
> > 
> > DROP TABLE IF EXISTS `galleries`;
> > 
> > KEY `node_key` (`node_id`),  
> > CURRENT\_TIMESTAMP on update CURRENT\_TIMESTAMP,  
> > `created_on` timestamp NOT NULL default  
> > ) ENGINE=MyISAM DEFAULT CHARSET=latin1;

* * *

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

* * *

Telefonate ohne weitere Kosten vom PC zum PC: [http://messenger.yahoo.de](http://messenger.yahoo.de)

---

<div class="post-metadata">

**Author:** ![Luca\_Marinucci](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/f08c70/32.png) [@Luca\_Marinucci](https://www.ruby-forum.com/u/Luca_Marinucci)\
**Post date:** [December 23, 2005, 2:04pm UTC](https://www.ruby-forum.com/t/oo-model-style-inheritance/50977/5 "2005-12-23T14:04:08Z")

</div>

> Rails (or more specifically ActiveRecord) is based  
> on a single table per inheritance tree model. So  
> all your Node subclasses will be persisted in the  
> NODE table. You should also add a ‘type’ column in  
> this table so that ActiveRecord can track what is  
> the type of persisted instances.

Thx for the quick response.

Ok, this is a very efficient method but it gets very  
complex if I will add new types in future because I  
need to also add the new coloumns to the NODE table.

Perhaps the easier and better way is to use  
aggregation instead of inheritance with the model  
classes:

class Gallery \< ActiveRecord::Base  
has\_many :images  
belongs\_to :node  
end

Can you confirm that?

Cheers, Luca

> clean OO architecture of my models:The base object  
> modeled the db schema  
> ENGINEu003dMyISAM DEFAULT CHARSETu003dlatin1;DROP  
> ENGINEu003dMyISAM DEFAULT  
> (`gallery_id`), KEY `node_key` (`node_id`), KEY  
> defaultCURRENT\_TIMESTAMP on update  
> CURRENT\_TIMESTAMP,  
> CHARSETu003dlatin1;My question now is, is this a  
> nice design and is  
> thiseasy to implement with rails? And how should  
> Iimplement my models  
> in rails, should I use inheritanceor make sure that  
> each NODE  
> extensions sets thecorrect data in the NODE  
> table?Regards,

Luca\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_Telefonate

> ohne weitere Kosten vom PC zum PC:

http://messenger.yahoo.de\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_Rails

> mailing

removed\_email\_address@domain.invalid://lists.rubyonrails.org/mailman/listinfo/rails

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

* * *

Telefonate ohne weitere Kosten vom PC zum PC: [http://messenger.yahoo.de](http://messenger.yahoo.de)
