Understanding Enum in Ruby on Rails: A Complete Guide

Chetan MittalChetan Mittal
5 min read

Introduction to Enum in Rails

Enums in Ruby on Rails provide an elegant way to handle a set of predefined values for a column in your database. Introduced in Rails 4.1, the enum feature simplifies managing statuses, categories, and other types of enumerable values while improving readability and maintainability.

In this article, we will explore everything about enum, from basic usage to advanced techniques, along with code examples covering different Rails versions. We will also discuss best practices, common pitfalls, and how enums have evolved across Rails versions.

💡
We have written a complete book on “How to Master Enums” available freely. Access it here at https://allbooks.railsforgedev.com/2/mastering-enums

What is an Enum in Rails?

An enum in Rails is a feature that maps a set of symbolic values to integers in the database. Instead of storing strings like "active" or "inactive", Rails saves integer values (0, 1, etc.) and provides convenient query methods.

Benefits of Using Enum:

  • Performance: Integers are faster to query than strings.

  • Readability: Makes code more expressive and easier to understand.

  • Validation: Ensures values are limited to predefined options.

  • Automatic Query Methods: Rails generates helper methods for querying and updating.

  • Consistency: Enums enforce consistency in the database.

Defining an Enum in a Rails Model

Let's assume we have a User model where each user has a status (active, inactive, banned). Here’s how we define an enum:

class User < ApplicationRecord
  enum status: { active: 0, inactive: 1, banned: 2 }
end

Database Migration Example

To store enum values, we typically use an integer column:

class AddStatusToUsers < ActiveRecord::Migration[6.0]
  def change
    add_column :users, :status, :integer, default: 0
  end
end

Usage of Enums

Once defined, Rails provides convenient methods to interact with enums:

user = User.new(status: :active)
user.status # => "active"
user.active? # => true

user.banned!
user.status # => "banned"

Querying with Enums

Rails automatically generates scope methods to filter records:

User.active # Returns all users with status "active"
User.inactive # Returns all inactive users

You can also query using integer values:

User.where(status: 1) # Equivalent to User.inactive

Handling Enum with Validations

To ensure only valid values are assigned, you can use Rails validations:

class User < ApplicationRecord
  enum status: { active: 0, inactive: 1, banned: 2 }
  validates :status, inclusion: { in: statuses.keys }
end

Enum with Prefix and Suffix Options

Rails allows adding prefixes or suffixes to enum-generated methods to avoid naming conflicts:

class Order < ApplicationRecord
  enum state: { pending: 0, shipped: 1, delivered: 2 }, _prefix: :status
end

Now, method names will be:

order = Order.new
order.status_pending? # => true
order.status_shipped!

Advanced Enum Features

Multiple Enums in One Model

A model can have multiple enums:

class Employee < ApplicationRecord
  enum role: { developer: 0, manager: 1, hr: 2 }
  enum contract: { full_time: 0, part_time: 1, intern: 2 }
end

Now you can call:

employee = Employee.new(role: :developer, contract: :full_time)
employee.developer? # => true
employee.full_time? # => true

Enum with Custom Methods

You can define custom methods that use enums:

class User < ApplicationRecord
  enum status: { active: 0, inactive: 1, banned: 2 }

  def deactivate!
    update!(status: :inactive)
  end
end

Now you can call:

user = User.find(1)
user.deactivate!
user.inactive? # => true

Changing Enum Values Safely

If you need to change enum values, be cautious:

class ChangeStatusEnumInUsers < ActiveRecord::Migration[6.1]
  def change
    change_column_default :users, :status, from: 0, to: 1
  end
end

Use rake db:migrate carefully when modifying enums to prevent incorrect mappings.

Enum in Different Rails Versions

  • Rails 4.1: Introduced enum.

  • Rails 5+: Supports assigning multiple enum values (array-style enum).

  • Rails 6: Enhanced database migrations for enums.

  • Rails 7+: Improved serialization for enums in APIs.

Common Mistakes with Enums

1. Forgetting to Use Integer Columns

Using string instead of integer can break the enum functionality:

# Incorrect
class AddStatusToUsers < ActiveRecord::Migration[6.0]
  def change
    add_column :users, :status, :string, default: "active"
  end
end

2. Renaming Enum Keys Without Migration

Renaming an enum key without updating the database can lead to data inconsistency.

3. Overlapping Integer Values

Ensure unique integer values for enum keys to avoid conflicts.

FAQ

1. What is an enum in Rails?

Enums in Rails are a way to map symbolic names to integer values in the database, making it easier to handle predefined states.

2. How do I define an enum in Rails?

You can define an enum in a model using the enum keyword and mapping symbols to integers.

3. Can I use multiple enums in a single model?

Yes, Rails allows defining multiple enums in a single model, each with its own set of values.

4. What are common mistakes when using enums in Rails?

Some common mistakes include using string columns instead of integers, renaming enum keys without updating the database, and using overlapping integer values.

5. How can I safely update enum values?

You should use database migrations carefully when updating enum values to prevent data inconsistency.

6. What changes were introduced to enums in Rails 8?

Rails 8 introduces improved support for multiple value assignments, better integration with ActiveRecord queries, and enhanced serialization for API responses.

Conclusion

Enums in Rails provide a structured way to handle predefined values efficiently. They improve performance, enhance readability, and simplify querying and validations. By leveraging features like _prefix and _suffix, developers can avoid method conflicts while keeping code organized.

Use enums wherever applicable to write clean and maintainable Rails applications. If you are upgrading Rails, ensure your enums are compatible with new features and best practices.

0
Subscribe to my newsletter

Read articles from Chetan Mittal directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Chetan Mittal
Chetan Mittal

I stumbled upon Ruby on Rails beta version in 2005 and has been using it since then. I have also trained multiple Rails developers all over the globe. Currently, providing consulting and advising companies on how to upgrade, secure, optimize, monitor, modernize, and scale their Rails apps.