How to use Enum in Rails


Enum in Rails - SapidLabs

Enum in Rails

“Enum” for short for the word “Enumerator” is widely used in different programming languages to define different values that can be a constant. When it comes to Rails, enum plays an important role. How?


Example: Say you have a Post model in your rails application, and you have serveral states of the Post example :draft, :published and :trashed. Now, you want to query all the posts that are published or in draft or in trash state.

class Post < ApplicationRecord
  enum status: [ :draft, :published, :trashed ]
  # will be stored as 0,  1,  2 in the database.
end

You can define a state field as integer and map that to an enum state.


By using in our Post model, we get scopes based on the values we provided in enum.

Scopes provided by enum in Rails

For example: Here we get the following scopes:

  Post.draft => all the posts which are in `draft` state
  and
  Post.published => all the posts which are in `published` state
  and
  Post.trashed => all the posts which are in `trashed` state


Predicate methods provided by enum in Rails

Here, are the predicate methods that each Post instance will have:

  post = Post.first => returns the first post
  
  post.draft? => returns true the `Post` is in `draft` state
  and
  post.trashed? => returns true the `Post` is in `trashed` state
  and
  post.published? => returns true the `Post` is in `published` state


Good practice to declare enum in Rails

A good practice to follow while declaring enum in Rails is by creating it as a Hash. You will thank yourself later when it comes to changing those enums i.e adding and removing values. Something like the following:

class Post < ApplicationRecord
  
  enum state: {
    draft: 0,
    published: 1,
    trashed: 2
  }

end

Multiple enums with same value in rails

Say in our Post model we have another enum defined as comment_state which has all the three values we used for state i.e :draft, :published and :trashed.

Here comes _prefix and _suffix to the rescue. You can either use true option or the custom suffix you want to provide. By providing the _suffix: true the method that will be created will be as follows:

Using _suffix in rails enum

class Post < ApplicationRecord
  enum state: {
    draft: 0,
    published: 1,
    trashed: 2
  }, _suffix: true
end

# scopes available will be 
Post.draft_state
Post.published_state
Post.trashed_state

# methods 
post = Post.new
post.draft_state?

Using _prefix in rails enum

class Post < ApplicationRecord
  enum comment_state: {
    draft: 0,
    published: 1,
    trashed: 2
  }, _prefix: :comments
end

# scopes available will be 
Post.comments_draft
Post.comments_published
Post.comments_trashed

# methods 
post = Post.new
post.comments_draft?

Bonus: Negative Scopes in Rails 6

Read about Negative scopes in Rails.


Official Ruby Enum Guide

Recommended Posts

Default Enum in Rails 6
Rails 6 provides a way to define default enum value. Let’s see how it works...
Ruby 2.7 adds Enumerable#tally
After introducing the Enumerable#tally method in Ruby 2.7-preview updates. #tally as the name suggests gives...
How to rename column name in Rails
Rails rename_column Rails provides a simple method rename_column which can be used in a migration....