Rails 7 Enum

Techie     December 2022

Definition

In Rails, an enum is an attribute where the values map to integers in the database and can be queried by name.


Application Example

Suppose we have the orders table and we want to store the status attribute of an order object as either completed, pending or cancelled. Assuming there’s a status column of type integer in the table, having values 0, 1 and 2:


Defining an enum for the status attribute

# app/models/order.rb
class Order < ApplicationRecord
  enum :status, { completed: 0, pending: 1, cancelled: 2 }
end


Working with scopes

We can filter a query the regular way or by using the enum helper:

@orders = Order.all

@orders.where(status: "pending")

# or

@orders.pending


Checking for equality

We can check if an order is “completed” by using @order.status == “completed” or the enum helper:

@order = Order.find(params[:id])

@order.completed? # Returns true if @order.status == "completed"


Updating the enum

We can update the enum using the enum names or Rails helpers:

@order = Order.find(params[:id])

@order.update(status: :cancelled)

 # or
 
@order.cancelled! 


Enum options

1 . Using the prefix or suffix options to make it more intuitive:

class Order < ApplicationRecord
  enum :status, { completed: 0, pending: 1, cancelled: 2 }, prefix: true
end


@orders = Order.all

@orders.status_pending


2 . Disabling scope helper:

The scopes for status won’t be created as we have provided scopes: false:

# app/models/order.rb
class Order < ApplicationRecord
  enum :status, { completed: 0, pending: 1, cancelled: 2 }, prefix: true, scopes: false
end


3 . Opting for array instead of hash:

You can also use an array to define the enum but it’s not a good idea, because changing the order of the enum values will break the mapping.

# app/models/order.rb
class Order < ApplicationRecord
  enum :status, [:completed, :pending, :cancelled], prefix: true
end


Thanks for reading, see you in the next one!