When to Use Enums for a Cleaner and More Robust Rails Application

Jonathan Canaveral July 23, 2024

Enums for a Cleaner and More Robust Rails Application

Enums is a very powerful code pattern in rails.

It can be used to simplify handling status, category, or filtering of data in your data model.

 

What is the benefit?

Built-in Scopes and Methods

Let's say you have a model called Shipment.

You want a status and scoped data based on data statuses.

Let's say you have 3 different statuses for shipment, pending, out_for_delivery, and delivered. In a collection of Shipment data, you want to count all of the shipments that are pending.


Shipment.pending # will return a collection of shipment records that are pending.

The same goes for other statuses.

Another example is, you have a single instance of Shipment and you want to know its delivery status.


shipment = Shipment.find(..)
shipment.delivered?
=> false # returns a boolean

shipment.pending?
=> false # returns a boolean

shipment.out_for_delivery?
=> true # returns a boolean

As you can see, enums are also a powerful method to return shipment status.

 

Preventing Invalid Data

Enums keep the integrity of your data.

To make it more robust, always write a test for your enums


describe 'enums' do
  it 'defines the correct enum values for status' do
    expect(Order.statuses).to eq({ 'pending' => 0, 'shipped' => 1, 'delivered' => 2, 'canceled' => 3 })
  end
end
 

Why? This will prevent anyone from making unintended changes to your current enums.

 

Consistent Value Representation

Enums are always represented with integers as values in the database.

It prevents inconsistencies in how values are represented and interpreted across the application.

 

Readability and Maintainability

It makes things easier to understand.

The code is more readable and easier to understand, which is especially useful for new project developers.

 

How to use enums?

Based on our example above.

To add an enum to a Shipment model, create a migration like this:


class AddStatusToOrders < ActiveRecord::Migration[6.1]
  def change
    add_column :shipments, :status, :integer, default: 0, null: false
  end
end

Then update the Shipment model to include the delivery statuses.


class Order < ApplicationRecord
  enum status: { pending: 0, out_for_delivery: 1, delivered: 2, canceled: 3 }
end

 

Conclusion

Enums is a powerful tool, however, it is very easy to mess it up.

You just need to be extra careful when modifying enums especially if we are talking about a huge amount of data.

Remember to always write tests for all of your enums!

Have a diligent code review with your peers.

 

 

Ps. if you have any questions

Ask here