GAURAV VARMA
Rails 7.1 introduces a subtle but impactful improvement to enum handling with the addition of the validate
option.
The Problem Before
Enums have long been used in Rails to map symbolic values to integers — perfect for roles, states, or types. But assigning invalid enum values silently passed validation:
1class Holiday < ApplicationRecord
2 enum kind: [:national, :regional]
3end
4
5holiday = Holiday.new(kind: :optional)
6holiday.valid? # => true
In this case, :optional
isn't even defined in the enum, yet no error is raised until it's saved, which causes an ArgumentError
. That’s not great DX.
What’s New in Rails 7.1
Rails 7.1 now lets you enforce value-level validations with validate: true
:
1class Holiday < ApplicationRecord
2 enum kind: [:national, :regional], validate: true
3end
4
5holiday = Holiday.new(kind: :optional)
6holiday.valid? # => false
7holiday.errors[:kind] # => ["is not a valid kind"]
No more ArgumentErrors. Just clean, predictable validation failures.
Optional Enhancements
You can customize the validation further. For example, to allow nil
as a valid value:
1class Holiday < ApplicationRecord
2 enum kind: [:national, :regional], validate: { allow_nil: true }
3end
Now holiday.kind = nil
passes, but invalid values still fail validation.
Why It Matters
This change brings enums in line with the rest of Rails' validation philosophy — fail fast and fail clearly.
It’s especially helpful for apps accepting enum values via API params or forms, where invalid data might sneak in.
References
Summary
Enums are safer now. With validate: true
, Rails 7.1 lets your models reject invalid values before they hit the database — no surprises, just clean validations.