module HashParams::Validator
Public Instance Methods
validate(param, type=nil, validations={}) { |param, validations| ... }
click to toggle source
# File lib/hash_params/validator.rb, line 14 def validate(param, type=nil, validations={}) coercions = Array(validations[:coerce]) << type if param.nil? && validations[:default] param = validations[:default].respond_to?(:call) ? validations[:default].call() : validations[:default] end #if there is a :validate lambda run that too if validations[:validate] && validations[:validate].respond_to?(:call) param = validations.delete(:validate).call(param) end #don't bother with the rest if required parameter is missing if validations[:required] && param.nil? raise ValidationError.new('Required Parameter missing and has no default specified') end if block_given? && !param.is_a?(Hash) param = yield(param, validations) end # do all coercion and transformation first there could be an array of coersions they will be run in order coercions.each do |c| param = coerce(param, c, validations) end if param.is_a?(Hash) param = if block_given? HashParams::HashValidator.new.validate_hash(param, validations, &Proc.new) else HashParams::HashValidator.new.validate_hash(param, validations) end end #don't bother with the rest if required parameter is missing if validations[:required] && param.nil? raise ValidationError.new('Required Parameter missing and has no default specified') end errors = [] error = nil validations.each do |key, value| error = case key when :blank 'Parameter cannot be blank' if !value && (param.nil? || (param.respond_to?(:empty) && param.empty)) #)!value && blank?(value) when :format "#{param} must be a string if using the format validation" && next unless param.kind_of?(String) "#{param} must match format #{value}" unless param =~ value when :is "#{param} must be #{value}" unless param === value when :in, :within, :range "#{param} must be within #{value}" unless value.respond_to?(:include) ? value.include?(param) : Array(value).include?(param) when :min "#{param} cannot be less than #{value}" unless value <= param when :max "#{param} cannot be greater than #{value}" unless value >= param when :min_length "#{param} cannot have length less than #{value}" unless value <= param.length when :max_length "#{param} cannot have length greater than #{value}" unless value >= param.length else nil end if error error = validations[:errmsg] || error errors << error end end raise ValidationError.new(errors.join("\n")) unless errors.empty? param end
with_binding(&code)
click to toggle source
# File lib/hash_params/validator.rb, line 10 def with_binding(&code) BindingValidator.new.with_binding(&code) end
Private Instance Methods
coerce(val, type=nil, opts={})
click to toggle source
# File lib/hash_params/validator.rb, line 90 def coerce(val, type=nil, opts={}) # exceptions bubble up #order is important #if type is nil just return the object return val if type.nil? #two special types of transforms #There is no Boolean type so we handle them special if type.to_s == 'boolean' return val if (val == true || val == false) return false if /(false|f|no|n|0)$/i === val.to_s.downcase return true if /(true|t|yes|y|1)$/i === val.to_s.downcase # if we can't parse we return a nil # maybe !!val is a better return? raise CoercionError.new("Unable to coerce #{val} to boolean") end #they have given us a coercion which is a string or symbol which is not "boolean", we are going to cast this into a proc and run it return type.to_proc.call(val) if type.is_a?(Symbol) || type.is_a?(String) #could be a proc return type.call(val) if type.respond_to?(:call) #nothing but simple types left return val if val.is_a?(type) return val.to_s.to_sym if type == Symbol return Integer(val) if type == Integer return Float(val) if type == Float return String(val) if type == String return Date.parse(val) if type == Date return Time.parse(val) if type == Time return DateTime.parse(val) if type == DateTime return Array(val.split(opts[:delimiter] || ',')) if type == Array return Hash[val.gsub(/[{}]/, '').gsub('}', '').split(opts[:delimiter] || ',').map {|c| c.split(opts[:separator] ||':').map {|i| i.strip}}] if type == Hash raise CoercionError("Unable to coerce #{val} to #{type}") end