More control over enum in Rails 7.1

JetThoughts
JTWay
Published in
2 min readFeb 29, 2024

--

ActiveRecord::Enum in Rails have long been a convenient tool for representing a set of symbolic values within a model. However, using enum can sometimes lead to unexpected behavior, especially when it comes to the automatic generation of instance methods.
For instance, consider an Order model with an enum for status:

class Order < ApplicationRecord
enum status: [:pending, :processed]
end

Instance objects would have a convenient methods like order.pending?, order.processed?.
One of common possible issues with generated instance methods might be naming conflicts. For example, if we need to add a new status persisted for our Order model.

class Order < ApplicationRecord
enum status: [:pending, :processed, :persisted]
end

Simple adding it to the enum definition would lead to an ArgumentError:

You tried to define an enum named "status" on the model "Order", 
but this will generate a instance method "persisted?",
which is already defined by Active Record. (ArgumentError)

We can fix it by adding _prefix/_suffix option for the enum:

class Order < ApplicationRecord
enum status: [:pending, :processed, :persisted], _prefix: true
end

But then we’ll have to update #pending?/#processed? usages to #status_pending?/#status_processed?.

With Rails 7.1

In Rails 7.1, a new option _instance_methods is introduced, allowing developers to opt-out of the automatic generation of instance methods for enum. When enum is defined with _instance_methods: false, Rails will no longer generate methods like pending?, processed?, etc.

class Order < ApplicationRecord
enum status: [:pending, :processed, :persisted], _instance_methods: false
end

Now we can define custom methods tailored to the specific needs without worrying about conflicts with automatically generated enum methods.

Benefits

  • Reduced Method Clutter: By disabling the automatic generation of enum methods, we can keep model interfaces cleaner and more focused.
  • Flexibility in Method Naming: With enum instance methods disabled, we have the freedom to name methods the way we want to make the codebase more expressive and easier to understand.
  • Avoidance of Method Name Conflicts: In scenarios where enum method names clash with existing or future method names in the model, disabling enum instance methods can prevent potential conflicts and bugs.
  • Improved Performance: By reducing the number of automatically generated methods, there may be a slight improvement in application performance, especially in cases where models have numerous enum attributes.

Dmitry Tsvetkov is a Software Engineer at JetThoughts. Follow him on LinkedIn or GitHub.

If you enjoyed this story, we recommend reading our latest tech stories and trending tech stories.

--

--