module CouchRest::Validation::AutoValidate

Public Instance Methods

auto_generate_validations(property) click to toggle source

Auto-generate validations for a given property. This will only occur if the option :auto_validation is either true or left undefined.

@details [Triggers]

Triggers that generate validator creation

:nullable => false
    Setting the option :nullable to false causes a
    validates_presence_of validator to be automatically created on
    the property

:size => 20 or :length => 20
    Setting the option :size or :length causes a validates_length_of
    validator to be automatically created on the property. If the
    value is a Integer the validation will set :maximum => value if
    the value is a Range the validation will set :within => value

:format => :predefined / lambda / Proc
    Setting the :format option causes a validates_format_of
    validator to be automatically created on the property

:set => ["foo", "bar", "baz"]
    Setting the :set option causes a validates_within
    validator to be automatically created on the property

Integer type
    Using a Integer type causes a validates_numericality_of
    validator to be created for the property.  integer_only
    is set to true

Float type
    Using a Integer type causes a validates_is_number
    validator to be created for the property.  integer_only
    is set to false, and precision/scale match the property

Messages

:messages => {..}
    Setting :messages hash replaces standard error messages
    with custom ones. For instance:
    :messages => {:presence => "Field is required",
                  :format => "Field has invalid format"}
    Hash keys are: :presence, :format, :length, :is_unique,
                   :is_number, :is_primitive

:message => "Some message"
    It is just shortcut if only one validation option is set
# File lib/couchrest/validation/auto_validate.rb, line 90
def auto_generate_validations(property)
  return unless ((property.autovalidation_check != true) && self.auto_validation)
  return if (property.options && (property.options.has_key?(:auto_validation) && !property.options[:auto_validation]) || property.read_only)
  # value is set by the storage system
  opts = {}
  opts[:context] = property.options[:validates] if property.options.has_key?(:validates)

  # presence
  if opts[:allow_nil] == false
    validates_presence_of property.name, options_with_message(opts, property, :presence)
  end

  # length
  if property.type_class == String
    # XXX: maybe length should always return a Range, with the min defaulting to 1
    # 52 being the max set 
    len = property.options.fetch(:length, property.options.fetch(:size, 52))
    if len.is_a?(Range)
      opts[:within] = len
    else
      opts[:maximum] = len
    end
    validates_length_of property.name, options_with_message(opts, property, :length)
  end

  # format
  if property.options.has_key?(:format)
    opts[:with] = property.options[:format]
    # validates_format property.name, opts
    validates_format property.name, options_with_message(opts, property, :format)
  end

  # uniqueness validator
  if property.options.has_key?(:unique)
    value = property.options[:unique]
    if value.is_a?(Array) || value.is_a?(Symbol)
      # validates_is_unique property.name, :scope => Array(value)
      validates_is_unique property.name, options_with_message({:scope => Array(value)}, property, :is_unique)
    elsif value.is_a?(TrueClass)
      # validates_is_unique property.name
      validates_is_unique property.name, options_with_message({}, property, :is_unique)
    end
  end

  # within validator
  if property.options.has_key?(:set)
    validates_within property.name, options_with_message({:set => property.options[:set]}, property, :within)
  end

  # numeric validator
  if property.type_class == Integer
    opts[:integer_only] = true
    validates_numericality_of property.name, options_with_message(opts, property, :is_number)
  elsif Float == property.type_class
    opts[:precision] = property.precision
    opts[:scale]     = property.scale
    validates_numericality_of property.name, options_with_message(opts, property, :is_number)
  end
  
  # marked the property as checked
  property.autovalidation_check = true
  
end
options_with_message(base_options, property, validator_name) click to toggle source

adds message for validator

# File lib/couchrest/validation/auto_validate.rb, line 22
def options_with_message(base_options, property, validator_name)
  options = base_options.clone
  opts = property.options
  options[:message] = if opts[:messages]
    if opts[:messages].is_a?(Hash) and msg = opts[:messages][validator_name]
      msg
    else
      nil
    end
  elsif opts[:message]
    opts[:message]
  else
    nil
  end
  options
end