www.flickr.com
|
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:
The table definition for these two classes using rails migration mechanism, is:
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:
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
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.
class Dog < Animal
end
class Animal < ActiveRecord::Base
end
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
end
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
end
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