When to Use Enums for a Cleaner and More Robust Rails Application
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