2025-05-03

Enums with sqlite

At the time of this article SQLite does not support the enum column type. We can still define and use enums in Active Record with the enum helper which was introduced in Rails 7.

We can define the column using Integer or String. In the following example, I will use strings. If you choose to use Integer you’ll have to update the check_contraint.

class CreateUsers < ActiveRecord::Migration[8.0]
  def change
    create_table :users do |t|
      t.string :email_address, null: false
      t.string :password_digest, null: false

      t.string :role, null: false, default: "admin"
      t.check_constraint "role IN ('admin', 'instructor', 'student')", name: "role_check"

      t.timestamps
    end
    
    add_index :users, :email_address, unique: true
    add_index :users, :role
  end
end

Next, I will define those roles with the enum helper in the User model.

class User < ApplicationRecord
  has_secure_password
  has_many :sessions, dependent: :destroy

  enum :role, { admin: "admin", instructor: "instructor", student: "student" }, prefix: true

  normalizes :email_address, with: ->(e) { e.strip.downcase }

  validates :role, presence: true
end

Defining an enum in Active Record provides useful instance methods. We will now be able to call:

User.role_admin? User.not_admin

user = User.create!
user.role
# => "admin"
user.role_student!
user.role
# => "student"