DEV Community

Code Salley
Code Salley

Posted on

Ruby Single Table Inherency (STI)

From a personal experience, In a recent interview for a rails developer position, i was asked to implement something simple but tricky. eg:

"We need an application to create a post, comments, and replies with only two tables, how will you approach it."

  • All i could think of was creating a boolean column in comments table to trigger replies. After the session, the interviewer gave me a straight tip on what he expected and that's single table inheritance(STI).
  • We've 'Posts table' and 'Comments table', after generating our models and migrating, we can create another class 'Replies' to inherit from 'Comments'. eg

Post model

Rails generate model post title:string
Enter fullscreen mode Exit fullscreen mode

above we generate a model Post with a title column.

Comments model

Rails generate  model comment title:string type:string
Enter fullscreen mode Exit fullscreen mode

above is a comments model with title and type, you might be wondering why type? well, we need a column to hold replies type. creating a reply will be saved as a type.

let's generate a replies model.

Rails generate model reply --parent=Comment
Enter fullscreen mode Exit fullscreen mode

Yes, about the flag used --parent a normal model inherits from active record by default but here we want our model to inherit from Comment model, adding the flag generate something like this

class Reply < Comment
Enter fullscreen mode Exit fullscreen mode

we can comments and replies

# comment
comment = Comment.create(title: "hello comment")

# reply = Reply.create(title: "hello title")
Enter fullscreen mode Exit fullscreen mode

Reply SQL looks like

INSERT INTO "comments" ("type", "title") VALUES ('Reply', 'hello title')
Enter fullscreen mode Exit fullscreen mode

You should always try to avoid Single Table Inherency(STI), it makes models associations complicated

Discussion (2)

leouofa profile image
Leonid Medovyy

Both STI and polymorphic associations are challenging to wrap the head around, but under the right circumstances can be massive timesaver.

codesalley profile image
Code Salley Author

i agree