OO model style: inheritance


#1

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


#2

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

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

cheers
Gerret


#3

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


#4

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

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


Telefonate ohne weitere Kosten vom PC zum PC: http://messenger.yahoo.de


#5

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


Telefonate ohne weitere Kosten vom PC zum PC: http://messenger.yahoo.de