There is often a debate with respect to when and how best to implement Single Table Inheritance. We will call it STI. There is also another argument between using Polymorphic Association and Single Table Inheritance. That is however beyond the scope of this article. So we will focus mainly on Implementing Single Table Inheritance.
What is Single Table Inheritance (STI)
This is a design pattern where a super class is inherited by a subclass (many subclasses can exist). For instance, when an edutech application has a User model, it can be inherited by lecturer and student models, where lecturer and student are different types of users.
Let’s get started with the STI implementation of the day.
Creating a Rails Application
We will create an application that has User, Lecturer and Student models. Let’s call it edutech. Go to your project directory via the terminal and run the command below to create a new rails application.
rails new edutech -d postgresql
The above command will create a rails application called edutech with postgresql as the database of choice.
Let’s create the user model with email and password. But before we create the user model, add the line below to your Gemfile to ensure the passwords are encrypted.
After that, run
bundle install to install the
Run the next command to create a User model.
rails generate model user email:string password_digest type:string
This creates the user resource which the other classes will inherit from. The password_digest is used because of the bcrypt gem. The type column tells ActiveRecord that the user model will have subclasses, and as such when a user is created, the type attribute is added with respect to the type of user. It could be a lecturer or a student in our case.
has_secure_password to support
bcrypt in the User model. After adding basic validations for email and password, the user model looks like this:
# user.rb class User < ApplicationRecord has_secure_password validates :email, presence: true validates :passwordl, presence: true end
Let’s create the other two models, Lecturer and Student. The diagram below depicts what we are trying to achieve.
The three models should contain the code below but first we create files named lecturer.rb and student.rb in the model folder respectively.
Create two more files in the model folder and name them
student.rb respectively. Copy the code below to their respective files.
# lecturer.rb class Lecturer < User validates :lecturer_code, presence: true validates :appointment_date, presence: true end
# student.rb class Student < User validates :student_code, presence: true validates :level, presence: true end
From the classes above, we can see that the Lecturer and Student models inherit from the User model. Thus, they are subclasses of the User model.
If we create a new student,
Student.create(student_params), the user table is updated with the new object and the
Type column is set to
This brings us to the end of our article on Single Table Inheritance(STI).