Michael Kovacs' photos More of Michael Kovacs' photos
Recommend Me Cable Car Software logo

Sunday, January 08, 2006

Rails realities part 5 (single table inheritance gotcha)

I came across my first need for using model inheritance yesterday and so I dug a little deeper into active record and the only support currently is for single table inheritance. That means that all classes in a hierarchy have their attributes stored in the same table. For example:

class Dog < Animal

class Animal < ActiveRecord::Base

The table definition for these two classes using rails migration mechanism, is:

create_table :Animals do |t|
t.column :type, :string
t.column :fetches, :boolean
t.column :runs, :boolean

The type column is used by rails to determine what object type to instantiate with the data in a given row. Fetches is intended to be a property on Dog while runs is intended to be a property on Animal. Turns out in reality that both of these properties will be present on both of these types because there's no way to specify any sort of encapsulation of these properties.

I actually gave it a shot by declaring the specific attr_accessors on each class, like this:

class Dog < Animal
attr_accessor :fetch

That turned out to be a mistake as declaring those attributes yielded an instance variable named @fetch and my property was empty when I did a dog.inspect

#< Dog:0x22b3114 @new_record=true, @errors=# < ActiveRecord::Errors:0x22b2fac @errors={}, @base=# < Dog:
0x22b3114 ...>>, @attributes={"fetch"=>nil, "runs"=>nil}, @fetch="true">

So be careful out there if you use STI. Turns out you can be very OO when using it. Hopefully I'm missing something here but it appears that there needs to be a way to declare what fields go in what class in the hierarchy.


Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?