Question

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.

Was it helpful?

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

OTHER TIPS

I think it might an issue with your regular expression. If you're trying to match any string with digits you should have something like /\A\D*\d+\D*\z/ right now you're matching a ton of stuff that I don't think you want.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top