Single table inheritance - HowTo?


#1

Hi,

As per another member’s suggestion, I’m trying to user STI. So I have
this table:

CREATE TABLE settings (
id int(11) unsigned NOT NULL auto_increment,
type char(40) NOT NULL default ‘General’,
name char(40) NOT NULL default ‘’,
value char(128) NOT NULL default ‘’,
updated_on datetime default NULL,
comments char(255) default NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

And a row with a type = ‘General’, and name = ‘front-page’

Then I have a setting.rb model, and also general_setting.rb and
user_setting.rb, where I only have:

class Setting < Setting
end

So, if I do General.find_by_name(‘front-page’), I expected to get the
value of the corresponding row, instead I get a nil object.

What could I possibly be doing wrong?

Thanks!

Ivan V.


#2

[Note: HowTo in the subject suggests you’re providing a HowTo. You’re
not.
You’re asking a question.]

On Fri, Jan 06, 2006 at 03:59:18PM -0600, Iván Vega R. wrote:

PRIMARY KEY (id)
So, if I do General.find_by_name(‘front-page’), I expected to get the
value of the corresponding row, instead I get a nil object.

The value of the type field should be the name of the subclass you wish
to
instantiate for that row. So if your class is named GeneralSetting, you
should be inserting type=‘GeneralSetting’.

  • Matt

#3

Iván

The ‘type’ column is used by Rails in the background and, most of the
time, there is no need for you to manipulate it explicitly.

So, if you have
class Foo < ActiveRecord
and
class SuperFoo < Foo

, you can query them directly:

allRecords = Foo.find(:all)
onlyTheSuperFoos = SuperFoo.find(:all)

Did that answer your question?

Alain


#4

Matthew, although a bit crankyly ;-), had the answer. I wasn’t using the
correct type name for each class.

Although you do make a point. I should’ve used your method to test how
STI worked in the first place.

Thanks!

Ivan V.