Module: Modelish::Validations::ClassMethods

Defined in:
lib/modelish/validations.rb

Instance Method Summary collapse

Instance Method Details

#add_validator(property_name, &validator) ⇒ Object

Sets up a block containing validation logic for a given property. Each property may have 0 or more validators.

Examples:

adding a validator that only allows non-nil values

class MyModel
  include Modelish::Validations
  attr_accessor :foo
  add_validator(:foo) { |val| val.nil? ? 'foo must not be nil': nil }
end

Parameters:

  • property_name (String, Symbol)

    the name of the property to validate

  • validator (#call)

    the block containing the validation logic; must return either an error object or a string containing the error message if validation fails.



67
68
69
70
71
72
73
74
# File 'lib/modelish/validations.rb', line 67

def add_validator(property_name, &validator)
  validators[property_name.to_sym] ||= [] 
  validators[property_name.to_sym] << validator

  class_eval do
    attr_accessor property_name.to_sym unless method_defined?(property_name.to_sym)
  end
end

#validate_length(name, value, max_length) ⇒ Object

Validates the length of a value, returning an error when validation fails.

Parameters:

  • name (Symbol, String)

    the name of the property/argument to be validated

  • value (#length)

    the value to be validated

  • max_length (#to_i)

    the maximum allowable length

Raises:

  • (ArgumentError)

    when the value is longer than max_length



136
137
138
139
140
# File 'lib/modelish/validations.rb', line 136

def validate_length(name, value, max_length)
  if max_length.to_i > 0 && value.to_s.length > max_length.to_i
    ArgumentError.new("#{name} must be less than #{max_length} characters")
  end
end

#validate_length!(name, value, max_length) ⇒ Object

Validates the length of a value, raising an error to indicate validation failure.

Parameters:

  • name (Symbol, String)

    the name of the property/argument to be validated

  • value (#length)

    the value to be validated

  • max_length (#to_i)

    the maximum allowable length

Raises:

  • (ArgumentError)

    when the value is longer than max_length



116
117
118
119
# File 'lib/modelish/validations.rb', line 116

def validate_length!(name, value, max_length)
  error = validate_length(name, value, max_length)
  raise error if error
end

#validate_length?(name, value, max_length) ⇒ true, false

Validates the length of a value, returning a boolean to indicate validation success.

Parameters:

  • name (Symbol, String)

    the name of the property/argument to be validated

  • value (#length)

    the value to be validated

  • max_length (#to_i)

    the maximum allowable length

Returns:

  • (true, false)

    true if value does not exceed max_length; false otherwise



126
127
128
# File 'lib/modelish/validations.rb', line 126

def validate_length?(name, value, max_length)
  validate_length(name, value, max_length).nil?
end

#validate_required(args) ⇒ Array<ArgumentError>

Validates the required values, returning a list of errors when validation fails.

Parameters:

  • args (Hash)

    the map of name => value pairs to validate

Returns:

  • (Array<ArgumentError>)

    a list of ArgumentErrors for validation failures.



86
87
88
89
90
91
92
# File 'lib/modelish/validations.rb', line 86

def validate_required(args)
  errors = []
  args.each do |name, value|
    errors << ArgumentError.new("#{name} must not be nil or blank") if value.nil? || value.to_s.strip.empty?
  end
  errors
end

#validate_required!(args) ⇒ Object

Validates the required values, raising an error when validation fails.

Parameters:

  • args (Hash)

    the map of name => value pairs to validate

Raises:

  • (ArgumentError)

    when any value in args hash is nil or empty. The name key will be used to construct an informative error message.



99
100
101
102
# File 'lib/modelish/validations.rb', line 99

def validate_required!(args)
  errors = validate_required(args)
  raise errors.first unless errors.empty?
end

#validate_required?(args) ⇒ true, false

Validates the required values, returning a boolean indicating validation success.

Parameters:

  • args (Hash)

    the map of name => value pairs to validate

Returns:

  • (true, false)

    true when validation passes; false when validation fails



108
109
110
# File 'lib/modelish/validations.rb', line 108

def validate_required?(args)
  validate_required(args).empty?
end

#validate_type(name, value, type) ⇒ ArgumentError

Validates the type of the value, returning an error when the value cannot be converted to the appropriate type.

Parameters:

  • name (Symbol, String)

    the name of the property/argument to be validated

  • value (Object)

    the value to be validated

  • type (Class, Proc)

    the type of the class to be validated. Supported types include:

    • +Integer+
    • +Float+
    • +Date+
    • +DateTime+
    • +Symbol+
    • any arbitrary +Class+ -- validates based on the results of is_a?

Returns:

  • (ArgumentError)

    when validation fails



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/modelish/validations.rb', line 176

def validate_type(name, value, type)
  error = nil

  begin
    if value && type
      # Can't use a case statement because of the way === is implemented on some classes
      if type == Integer
        is_valid = (value.is_a?(Integer) || value.to_s =~ /^\-?\d+$/)
      elsif type == Float
        is_valid = (value.is_a?(Float) || value.to_s =~ /^\-?\d+\.?\d*$/)
      elsif [Date, DateTime].include?(type)
        is_valid = value.is_a?(type) || (type.parse(value.to_s) rescue false)
      elsif type == Symbol
        is_valid = value.respond_to?(:to_sym)
      else
        is_valid = value.is_a?(type)
      end

      unless is_valid
        error = ArgumentError.new("#{name} must be of type #{type}, but got #{value.inspect}")
      end
    end
  rescue StandardError => e
    error = ArgumentError.new("An error occurred validating #{name} with value #{value.inspect}: #{e.message}")
  end

  error
end

#validate_type!(name, value, type) ⇒ Object

Validates the type of the value, raising an error when the value is not of the correct type.

Parameters:

Raises:

  • (ArgumentError)

    when the value is not the correct type

See Also:



158
159
160
161
# File 'lib/modelish/validations.rb', line 158

def validate_type!(name, value, type)
  error = validate_type(name, value, type)
  raise error if error
end

#validate_type?(name, value, type) ⇒ true, false

Validates the type of the value, returning a boolean indicating validation outcome.

Parameters:

Returns:

  • (true, false)

    true when the value is the correct type; false otherwise

See Also:



148
149
150
# File 'lib/modelish/validations.rb', line 148

def validate_type?(name, value, type)
  validate_type(name, value, type).nil?
end

#validatorsObject

A map of registered validator blocks, keyed on property_name.



77
78
79
# File 'lib/modelish/validations.rb', line 77

def validators
  @validators ||= {}
end