Enum in Ruby

Nurudeen Ibrahim Feb 23, 2022
  1. Use a Module to Implement Enums in Ruby
  2. Use a Hash to Implement Enums in Ruby
  3. Enums in Rails Using Ruby
Enum in Ruby

Enum is a data type that contains a fixed set of constants, usually mapped to integer values. Ruby does not have a built-in Enum type, unlike many other programming languages.

Although Enums feature was introduced in Rails 4.1 using some custom implementation.

Use a Module to Implement Enums in Ruby

We will have an enum called Status with sets of predefined values, PENDING, IN_PROGRESS, and COMPLETE.

module Status
  PENDING = 1
  IN_PROGRESS = 2
  COMPLETE = 3
end

puts Status::PENDING
puts Status::IN_PROGRESS
puts Status::COMPLETE

Output:

1
2
3

Each of these three elements is mapped to an integer value so that wherever we see status of 1, it means we’re referring to a PENDING status while 2 and 3 refer to IN_PROGRESS and COMPLETE.

This design is useful only if we want to reference the enum values in different areas of our code.

Use a Hash to Implement Enums in Ruby

STATUS = {
  pending: 1,
  in_progress: 2,
  complete: 3
}

def status_string(value)
  STATUS.key(value)
end

puts STATUS[:pending]
puts status_string(2)

Output:

1
in_progress

The design above allows you to access the status value and the status element (type). This is useful if the enum is mapped to a status field.

Enums in Rails Using Ruby

Rails 4.1 introduced the concept of enum, and it comes in handy when you have a complex value like status described above that needs to be stored in the database.

For example, a Project model can have a status field that would be an enum, and we defined that as shown below.

## Project model
class Project
  ##
  enum status: {
    pending: 1,
    in_progress: 2,
    complete: 3
  }
end

The status field in the database is defined as an integer field. For a pending status project, 1 is stored, 2 for in_progress, and 3 is stored for a completed project.

Rails automatically create some methods under the hood that make working with an enum field easy and based on our status example.

We would have the following useful methods created automatically by Rails.

  • status: project.status returns the status of a project.
  • pending?: project.pending? returns true if a project is pending and false otherwise.
  • in_progress?: project.in_progress? returns true if a project is in progress and false otherwise.
  • complete?: project.complete? returns true if a project is complete and false otherwise.
  • pending!: project.pending! updates a project’s status to pending.
  • in_progress!: project.in_progress! updates a project’s status to in_progress.
  • complete!: project.complete! updates a project’s status to complete.