Search code examples
ruby-on-railsrubyruby-on-rails-3inheritancecustom-validators

Inheritance with Custom Validators Ruby on Rails


I was trying to create a custom validator class in Ruby on Rails that can be expanded. However, I cannot get it to use validation from both the sub-class and super-class. This example will clarify what I am trying to achieve:

Super-class

class NameValidator < ActiveModel::EachValidator
   def validate_each (record, attribute, value)

       #Checks to see if the incoming string is free of any numerical characters
        if value.match(/\A[+-]?\d+\Z/)
        record.errors[attribute] << "String must contain no numerical characters"
        end
   end
end

sub-class

class SevenNameValidator < NameValidator

     def validate_each (record, attribute, value)

         # Checks and only allows 7 character strings to be validated
         if value.length != 7
            record.errors[attribute] << "String must be 7 characters exactly"
         end
     end
 end

Model class

class User < ActiveRecord::Base
  attr_accessible :firstname

  validates :firstname, :seven_name => true

end

so if the string "hello" is tested the resulting error => "Strings must be 7 characters exactly"

However if the string "hello77" is tested, it is validated successfully.

Shouldn't it check from NameValidator first and see that it has digits? If not, how can I get inheritance to work in custom validators? Do I need to use methods within my validator classes? An example would be appreciated, I have searched a lot, but I cannot find an example for custom validators.


Solution

  • Call super in sub-class:

    class SevenNameValidator < NameValidator
    
         def validate_each (record, attribute, value)
    
             # Checks and only allows 7 character strings to be validated
             if value.length != 7
                record.errors[attribute] << "String must be 7 characters exactly"
             else
               #call super to trigger super class method
               super 
             end
         end
     end