Search code examples
ruby-on-railsruby-on-rails-5.1

How to use ActiveModel::EachValidator in rails 5


How to validate specific attribute using ActiveModel::EachValidator. I have written the below snippet of code. This validation will not call on saving or validating object.

class EmailValidator < ActiveModel::EachValidator
    def validate_each(record,attribute,value)
       # Logic to check email is valid or not
    end
end

This will work with rails 3.


Solution

  • A simple base class that can be used along with ActiveModel::Validations::ClassMethods#validates_with

    class User
      include ActiveModel::Validations
      validates_with EmailValidator
    end
    
    class EmailValidator < ActiveModel::Validator
      def validate(record)
         # Logic to check email is valid or not
         record.errors.add :email, "This is some complex validation"
      end
    end
    

    Any class that inherits from ActiveModel::Validator must implement a method called validate which accepts a record.

    To cause a validation error, you must add to the record's errors directly from within the validators message.

    For more details you can check here.

    If you are looking for only email validation then you can try this.

    class EmailValidator < ActiveModel::EachValidator
      def validate_each(record, attr_name, value)
        unless value =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
          record.errors.add(attr_name, :email, options.merge(:value => value))
        end
      end
    end