CodexBloom - Programming Q&A Platform

Problems with using custom validators in Rails 7 causing unexpected validation failures

šŸ‘€ Views: 9547 šŸ’¬ Answers: 1 šŸ“… Created: 2025-06-11
ruby rails active-model Ruby

Hey everyone, I'm running into an issue that's driving me crazy. Quick question that's been bugging me - I've been banging my head against this for hours. I'm working on a Rails 7 application and I've implemented a custom validator for my User model to ensure that the email domain is from a specific organization. However, I'm working with unexpected validation failures that I need to seem to resolve. Here's the custom validator I've set up: ```ruby class EmailDomainValidator < ActiveModel::Validator def validate(record) unless record.email =~ /@example\.com$/ record.errors.add(:email, 'must be from example.com domain') end end end ``` And I'm using it in my User model like this: ```ruby class User < ApplicationRecord validates_with EmailDomainValidator end ``` When creating a user with a valid email like `user@example.com`, it correctly passes the validation. However, when I try to save a user with an email from a different domain, like `user@test.com`, I see an behavior in the logs: ``` ActiveModel::behavior: Email must be from example.com domain ``` After checking, I confirmed that the validation should trigger in this case, which it does. But here's where it gets tricky: when I attempt to save a user with a nil email, Rails throws a `NoMethodError` because it's trying to call `=~` on `nil`. This is not what I expected, and it leads to the creation of an invalid user record with no email set. To prevent this, I thought about adding a check for `nil` in my validator, but I’m not sure of the best practice for this situation. I tried modifying the validator like this: ```ruby class EmailDomainValidator < ActiveModel::Validator def validate(record) return if record.email.nil? # Added check for nil unless record.email =~ /@example\.com$/ record.errors.add(:email, 'must be from example.com domain') end end end ``` Now, this prevents the `NoMethodError`, but I'm also wondering whether this is the right approach. Should I instead handle nils directly in the User model validation, or is there a better way to manage this in the custom validator? Any insights on best practices for implementing custom validators in Rails would be greatly appreciated. My development environment is macOS.