Search code examples
ruby-on-railssingle-table-inheritance

What are the merits of using STI vs Category?


This comes from the Rails world, but is a pretty generic question about Single Table Inheritance. They only reason I'm asking this is that people keep pushing STI on me when there is no obvious reason for it. May be I'm missing some point? Please consider these two scenarios for displaying & storing page contents for various pages on the website:

Scenario 1

class ContentItem < ActiveRecord::Base
  belongs_to category
end

Here all the possible items are stored in one table, only distinguished by the category. Then wherever you need to display all news items or faq items , you just do a call to category.

Scenario 2

class ContentItem < ActiveRecord::Base
  
end

class FaqItem < ContentItem
end

class NewsItem < ContentItem
end

Here there is no need for category, but if you ever need to add another type of ContentItem, you need to create another model, and another and so on.

My problem with scenario #2 is that FaqItem & NewsItems are exactly the same. They are never going to be different. The only difference is that they can be modified by different people ( Site Admin vs PR person for news) .

So while both approaches are ok, why choose one scenario over the other in this particular instance?


Solution

  • If there are only a few categories or types, and a lot of code is shared, it is very manageable to put it in one class. But once the list grows, your code will be scattered with case statements or if-trees, and this is where inheritance comes in handy.

    For instance:

    def title
      case category_id
        when 'FaqItem'
          do_1_thing
        when 'NewsItem'
          do_another_thing
      end
    end
    

    as opposed to

    class FaqItem < ContentItem
      def title
        do_1_thing
      end
    end  
    
    class NewsItem < ContentItem
      def title
        do_another_thing
      end
    end  
    

    The second solution will be more easily maintainable and understandable. There could be some duplication of code, but this could be solved by smartly using your parent class.

    Still: it is a matter of taste how soon you switch to using STI, that will depend on the complexity of your code.