Rails 7.1's New Feature: Validate Option for Enums

Rails 7.1 introduces a significant enhancement to enum handling through the introduction of the :validate option.

Before Rails 7.1

In earlier Rails versions, assigning an incorrect value to an enum would result in ArgumentError. Let’s illustrate this with an example:

1
2
3
4
5
6
7
class Product < ApplicationRecord
  enum status: [:available, :out_of_stock]
end

product = Product.last
product.status = :discontinued
# 'discontinued' is not a valid status (ArgumentError)

In the above snippet, the Product model has an enum column status, which can take :available or :out_of_stock as valid product statuses. When attempting to assign :discontinued as a product status, it raises an ArgumentError.

After Rails 7.1

Rails 7.1 introduces the validate option for enums, allowing developers to enforce validation checks before saving enum values. Let’s see the change introduced in this version:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Product < ApplicationRecord
  enum status: [:available, :out_of_stock], validate: true
end

product = Product.last

product.status = :discontinued
product.valid? # Output: false

product.status = nil
product.valid? # Output: false

product.status = :available
product.valid? # Output: true

Now, by passing validate: true, we can ensure that validation checks are in place before saving enum values. It enhances the control over the integrity of our data.

Additional Validation Options

Rails 7.1 also allows us to pass additional validation options:

1
2
3
4
5
6
7
8
9
10
11
class Product < ApplicationRecord
  enum status: [:available, :out_of_stock], validate: { allow_nil: true }
end

product = Product.last

product.status = :discontinued
product.valid? # Output: false

product.status = nil
product.valid? # Output: true

Here, the allow_nil: true option enables flexibility in handling nil values while validating the enum.