May 1, 2024
•Last updated May 2, 2024
Simplifying Data with Rails Single Table Inheritance
When you build apps with Ruby on Rails, managing a lot of data can be tricky, especially when different parts of your app are similar but not the same.
Rails has a cool feature called Single Table Inheritance (STI) that helps with this. This post explores how to use Rails' single table inheritance, why it's helpful, and other options you might consider if you’re not the biggest fan.
What is Rails Single Table Inheritance?
Rails single table inheritance (STI) allows different parts of your app to share the same table in the database. This makes it easier to handle your data because everything is in one place but can still act differently.
How to Set Up Rails Single Table Inheritance
Setting up STI in Rails means making one primary model and a table with a special column called type
. This column helps Rails figure out what kind of data is being stored. Here’s how you can do it:
Step 1: Create the Main Table
You need to make a table that holds all the data that your parts of the app will share. We’ll use a Vehicle
table as the main table in this example.
# Migration to create a vehicles table with STI support
class CreateVehicles < ActiveRecord::Migration[6.1]
def change
create_table :vehicles do |t|
t.string :type
t.string :make
t.string :model
t.integer :year
t.timestamps
end
end
end
Step 2: Make Models for Each Part
You create a primary model called Vehicle
and other models like Car
and Truck
that will act as the specific parts.
# app/models/vehicle.rb
class Vehicle < ApplicationRecord
end
# app/models/car.rb
class Car < Vehicle
end
# app/models/truck.rb
class Truck < Vehicle
end
With Rails STI, you can make and use cars or trucks easily, and Rails keeps track of what type they are when they are made based on the type
column.
Step 3: Using the Models
Just like any other part of your app, you can make new cars or find all trucks easily.
# Creating a new car
Car.create(make: 'Toyota', model: 'Corolla', year: 2021)
# Looking at all cars
Car.all
Querying for data
Now, we have more flexibility when it comes to queries. Say you want to query for all Trucks. There are a couple of approaches.
trucks = Vehicle.where(type: 'truck')
trucks_alt = Truck.all
When Should You Use Rails Single Table Inheritance?
It’s a good idea to use Rails STI when:
- Different parts of your app are almost the same.
- These parts share many features.
- You want to make finding and working with data simpler.
An example here might be an Entry
parent class that can be a Message
or Comment.
The Message
and Comment
class inherit from Entry
, thus creating a shared role where it makes sense.
Other Options Besides Rails Single Table Inheritance
Rails STI is great, but sometimes, it might make your table too big or mix up data. Here are some other ways to handle this:
Polymorphic Associations:
This lets parts of your app connect with many different models.
Using Gems for Table Inheritance:
Some tools, like the acts_as_tenant
gem, help keep things orderly, primarily if your app serves many users at once.
Multiple Table Inheritance:
This means making a separate table for each part but keeping the shared data lined up through extra code or database tricks.
Wrapping up
Rails single table inheritance is a handy tool for keeping your app's data neat and making your life easier when working with similar data. But remember, it's essential to choose the method that fits what your app needs the most. Pick the one that makes your app work best, whether it's STI or another technique. My best advice is to not force STI for the sake of using STI but instead if the exact setup makes sense for it. You don’t want to back into any corners you can’t escape.
Categories
Collection
Part of the Ruby on Rails collection
Products and courses
-
Hello Hotwire
A course on Hotwire + Ruby on Rails.
-
Hello Rails
A course for newcomers to Ruby on Rails.
-
Rails UI
UI templates and components for Rails.