Leveraging PostgreSQL 16 Enum Types in Rails 7+: A Step-by-Step Guide

Leveraging PostgreSQL 16 Enum Types in Rails 7+: A Step-by-Step Guide

If you're a Rails developer, you've probably heard about the recent improvements in Rails 8, including optimizations for SQLite. While I mainly use PostgreSQL for my projects, these updates have piqued my curiosity, and I'm always interested in exploring what's new.

In this article, I'll guide you through leveraging PostgreSQL 16 enums in Rails 7+, showing you how to add an enum column to an article model, allowing you to define specific categories like blog, snippet, and vlog. Enums offer better data integrity and readability, making your code more maintainable.

Adding an Enum Column to Your Rails Model

To add a category enum column to the articles table, start by generating a migration:

rails g migration AddCategoryToArticles category:string

Next, modify the generated migration as follows to create an enum type and assign it to the column:

class AddCategoryToArticles < ActiveRecord::Migration[7.2]
  def change
    create_enum :categories, %w[
      blog
      snippet
      vlog
    ]
    add_column :articles, :category, :enum, enum_type: :categories
    add_index :articles, :category
  end
end

Run the migration:

rails db:migrate

This will create an enum type called categories in PostgreSQL and add a corresponding enum column to the articles table. You can verify the change in the schema file, where you'll see both the enum definition and the updated column.

Defining Enum in Your Model

Now, let's add the enum definition in the Article model:

class Article < ApplicationRecord
  enum :category, {
    blog: "blog",
    snippet: "snippet",
    vlog: "vlog",
  }, validate: true

  validates :category, presence: true
end

The validate: true option ensures that the enum is validated automatically with inclusion checks. If the category field is required, make sure to backfill existing articles before adding validates :category, presence: true.

Adding a Scope for Filtering by Category

To easily filter articles by their category, you can add a scope to your model:

scope :by_category, ->(category) { where(category: category) }

This scope allows you to perform queries like Article.by_category("blog") to filter articles by a specific category.

Conclusion

Using PostgreSQL enums in Rails provides type safety and keeps your database schema organized. This approach is particularly useful for fields with a fixed set of values, like categories in a blog or types in a content management system.


Happy Coding!