More control over enum in Rails 7.1

jetthoughts-dev

JetThoughts Dev

Posted on February 29, 2024

More control over enum in Rails 7.1

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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

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

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 enums. 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
Enter fullscreen mode Exit fullscreen mode

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.

💖 💪 🙅 🚩
jetthoughts-dev
JetThoughts Dev

Posted on February 29, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related