# validate attributes have only alpha, numeric and whitespace require 'rails/alpha_numeric_validator/version' class AlphaNumericValidator < ActiveModel::EachValidator attr_accessor :string # :nodoc: PUNCTUATION_REGEXP = { default: /(?:[[:alpha:]]|[[:digit:]])+/, :true => /(?:[[:graph:]])+/, limited: /(?:[[:alpha:]]|[[:digit:]]|[_:\+\.\?,\-!'\/#])+/, # ' vim-color-syntax hack dns: /(?:[[:alpha:]]|[[:digit:]]|[\.\-])+/, fqdn: /(?:[[:alpha:]]|[[:digit:]]|-|\.)+/} WHITESPACE_EXCEPTIONS = [:dns, :fqdn] # == Creation # To use the AlphaNumericValidator, initialize it as any other class # # class ExampleValidator < ActiveRecord::Base # validates :attr1, alpha_numeric: true # validates :attr2, alpha_numeric: {punctuation: true} # validates :attr3, alpha_numeric: {punctuation: :limited} # validates :attr4, alpha_numeric: {allow_whitespace: true} # validates :attr4, alpha_numeric: {dns: true} # end def initialize(*args) # :nodoc: @errors = [] @record = nil super(*args) end # :call-seq: # validate_each :record, :attribute, :value # # :record:: AR instance # :attribute:: symbol for attribute # :value:: value to check validity def validate_each(record, attribute, value) #:nodoc: @record = record opts = {punctuation: :default} opts.merge! allow_whitespace: !WHITESPACE_EXCEPTIONS.member?(@options[:punctuation]) @options = opts.merge @options # TODO: document why value[1] @string = value.is_a?(Array) ? value[1] : value unless @string.nil? || @string.class.ancestors.include?(Numeric) || is_valid? record.errors[attribute] << 'invalid characters' end end # :call-seq: # is_valid? # # alias for :is_valid_string? def is_valid? is_valid_string? end # :call-seq: # is_valid_string? # # returns true if the string only contains the requested character set # # TODO: support international DNS def is_valid_string? return false if !@options[:allow_whitespace] && has_whitespace? re = PUNCTUATION_REGEXP[@options[:punctuation].to_s.to_sym] @string.to_s.gsub(re, "").blank? end # :call-seq: # has_whitespace? # # returns true if the string contains whitespace def has_whitespace? @string.to_s.match /(?:\s)+/ end end