Using Rails Single Table Inheritance to Avoid the “Type Of” Anti-Pattern

Ever have a situation where you have several entities in your application that are similar but not identical?   Perhaps they have the same attributes with a few exceptions, or perhaps their behavior is subtly different, or perhaps you want to display them differently.

In object oriented programming this is usually addressed with inheritance.  You define a base class that has the core attributes and behavior, then you extend it with classes that inherit from the base class and specialize the behavior.  Then your application code can work with objects in this class hierarchy without having special cases in the application code, it’s all tucked away in the objects instead.

If you have code in your controller that determines the behavior based on the class of the object it’s working with, or perhaps the value of an attribute, then you may be suffering from the type-of anti-pattern.  Ditto for view code that displays the object differently based on an indicator field.

I’d like to look at a simple example derived from a project I’m working on.  Imagine you were building a “micro blogging” site like tumblr where the blog entry can be a photo or something you write or something you link to.  One approach would be to define a type_of_post attribute.  Then in your model you can have your model check this value to determine which validations should be in effect.  And your view can have code that checks this value to see if it should display an image or a link.  This is completely lacking in object-oriented crunchy goodness.

Or you could have separate tables, one for image posts, another for text posts and yet another for posts that are a link to something else.  Then you have to deal with gathering all of these together and displaying them in the same views.  This sounds like a lot of dancing around.  Imagine the changes when someone has the bright idea that the application should support embedded videos from vimio and youtube?

In the bright and shiny world of object orientation this is often handled with inheritance.  Unfortunately, there is some dissonance between objects and the relational databases we store them in.  Databases don’t allow one table to extend another, and as Rails developers we don’t typically implement behavior in the database layer anyway.

Enter “Single Table Inheritance” as a simple solution.  Martin Fowler is the source for this design pattern. This is supported in rails, and it’s really easy to take advantage of.  I’ll post the specifics on how to use this, and an example app in part 2.

2 Responses to Using Rails Single Table Inheritance to Avoid the “Type Of” Anti-Pattern

  1. [...] Single Table Inheritance, Part 2 Previously I wrote about why you might want to use Single Table Inheritance in Rails. Let’s take a look at STI in action in a simple Rails [...]

  2. [...] Part III In the two previous posts I talked about Single Table Inheritance (STI) in Rails, first looking at the concept and why we might choose to represent our domain model like this, then we looked at an actual implementation where the goal was to be able to treat a heterogeneous [...]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.