Single Table Inheritance (STI) with ActiveRecord in Rails Discussion
Thanks Chris, It's funny that we just stopped using this design pattern at Gitlab
https://docs.gitlab.com/ee/development/database/single_table_inheritance.html
I read the article and it has very useful information. I'm curious how the Gitlab dev team would recommend approaching a problem I'm currently working on.
I'm adding STI to an events
table to track historical/audit data such as UserCreatedEvent
, UserUpdatedEvent
, etc. The primary benefit of using STI in this situation is I need to be able to display all the events for a given record in a single listing, with custom messages for each event. Using STI, I can make a single query user.events
and I have a list of all the events with custom messages displayed based on the class loaded via the type
column.
If I were to separate each event to a separate table, I would have multiple tables for each resource (ie, user_events
table, account_events
table, etc). And to display a list of events for a given record in a single sorted list, I would have to join on several tables and then possibly order the records in-memory to get them in chronological order.
I could probably create a view that implements this for me, but that adds a decent amount of complexity IMO.
I'm just curious if these types of situations are ones that Gitlab would utilize STI, or how would the Gitlab dev team handle implementing a feature like this? I definitely agree with the article overall, that STI should not be your first option, but I'm curious if they would ever recommend it for specific situations.
I do agree about the scale issue though; a single STI table does get large. I've been toying with the idea of using multiple databases where I archive data after a certain point to the other databases, and my primary database is streamlined only for recent data. Definitely adds some complexity with multiple databases though!
I'm just curious if these types of situations are ones that Gitlab would utilize STI, or how would the Gitlab dev team handle implementing a feature like this?
We still have some models leveraging STI. Ci::Build
for example is one of them. Given our growth and the complexity this brings we just decided to stop using this pattern.
Depending on your context and how much data you're dealing with, it might makes sense to continue using this pattern for your case.
Thanks for the episoded Chris!
What would you say are the main use cases that can benefit from STI ?
Nice! I used STI for an app with all types of documents, and I used the jsonb_accessor gem. It allows you to query the json fields just as if it were an active record column.
so my documents had just four columns but within the json column the table really looked more like this...
And I could just say InsuranceDocument.account_id even though it was technically InsuranceDocument.customData["account_id"]
I'm interested in delegated types as well.
At 2:34 the migration don't have foreign_key: true for t.belongs_to :event, null: false. What impact that make to not mention that?