Subclassing Models In Rails Is Called Single Table Inheritance
There’s one thing I’m beginning to not like about the Rails framework a little, and that’s the penchant that it has for making up names for concepts that already exist in programming languages.
If you have been programming in object-oriented frameworks for a while, you’d be surprised to know that Rails likes to call it “single table inheritance.” Why not just call it “class hierarchy” or maybe even “model hierarchy”?
Single Table Inheritance (or “STI,” which makes it sound a bit dirty), employs some Rails magic – as usual. The magic here is that the parent class has a table for itself in the database and is expected to have a column called type where you store the name of the child class – if a particular instance has the value of this column set, it implies that this record in the table for the parent class is not for an instance of the parent class but for that of a child class.
So of course, the astute among you will have noticed that this means that one table will have to hold all the columns corresponding to every single child class of that table’s model. So if you’re going to be “top-heavy” in your usage of the class hierarchy, then STI is not a good way to implement your hierarchy.
Here’s an example ripped off from this blog post, that’s at the top of the Google search results for “rails STI” (but with a mis-spelling corrected):
class Computer < ActiveRecord:Base # in app/models # Fields: # String name, owner, manufacturer, color, type end class Mac < Computer # in app/models # this is for Computers with type="Mac" before_save :set_color # Lets say all macs are silver, no point setting these ourselves def set_color self.color = "silver" self.manufacturer = "apple" end end
Notice that even though plain computers (as opposed to Macs) are colorless, a record for a computer (Computer.new) would set this column to nil in the Computer table.
Rails magic takes care of setting the value of the type column when you create instances of children classes.