As I dive into more Rails-y stuff, I was told about the concept of Single Table Inheritance. (s/o to MJ for introducing me to this!) This Rails design pattern is characterized by using a single table that stores data from multiple models that inherit from a base model (the parent class of STI) which inherits from ActiveRecord::Base.
(Whew!) OK, let me say that again…
STI is when you have a parent model class that has subclasses and they store data into a single table.
In the Rails console/database perspective, implementing STI is easier done than said [sic]. To generate models, you just have to do the normal “rails g” thingy.
After doing so, you can generate your subclass models by doing the following:
I learned that putting a “type” column in your parent model’s table is VERY IMPORTANT. The “type” column is like real-life magic because by default, ActiveRecord will search for that column for the STI to be in action. If you don’t want to use type, you can choose not to by defining something like below in your model. All of the tutorials I’ve read say that it’s better to use the default though.
Now, after you do a rake db:migrate, you’ll notice these models in your app.
In essence, that’s how you do implement STI in Rails. We can have a lot of submodels with only one table:
So now.. the interesting part!
How do we create new records? Is there something different? Well, the only different thing is that you always have to create a record with “type”:
It’s important that you know the type and the subclass exists because you’ll get an error if you input an incorrect type.
You can also create records from the submodel and it will be inserted into the database with the correct type automatically.
So there, it’s fun playing around with STI models. As you can see, it can be really useful in DRY-ing up your codes. However, there are some noticeable disadvantages as well.
Drawbacks (as I noticed)
- You can’t have the same name with different attribute data types– say the model has a column name and the other needs to be integer… you can’t STI no more!
- nil values when not used by subclass– you’ll have nil values all over your database if a lot of fields are not used by every subclass
The second thing that I was told about is combining STI with polymorphism. But that’s another story. I should blog about that next time!