While going source spelunking, I came across this piece of code in Rails' ActiveModel:
key = "#{key.to_s.camelize}Validator"
begin
validator = key.include?("::".freeze) ? key.constantize : const_get(key)
rescue NameError
raise ArgumentError, "Unknown validator: '#{key}'"
end
active_model/validations/validates.rb
This means that you can namespace your custom validators:
# lib/internal/email_validator.rb
module Internal
class EmailValidator
def validate_each(record, attribute, value)
return if value.ends_with?('@private_domain.com')
record.errors.add(attribute, 'not from private domain')
end
end
end
And then use them like this:
# app/models/admin.rb
class Admin < ApplicationRecord
validates :email, 'internal/email': true
end
Thanks to Bachir Çaoui for reviewing a draft version of this post.