Enum in Ruby
-
Use a
Module
to Implement Enums in Ruby -
Use a
Hash
to Implement Enums in Ruby - Enums in Rails Using 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 topending
.in_progress!
:project.in_progress!
updates a project’s status toin_progress
.complete!
:project.complete!
updates a project’s status tocomplete
.