Module: DataMapper::Validations::AutoValidations

Included in:
ClassMethods
Defined in:
lib/dm-validations/auto_validate.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#disable_auto_validationsObject (readonly)

Returns the value of attribute disable_auto_validations.



25
26
27
# File 'lib/dm-validations/auto_validate.rb', line 25

def disable_auto_validations
  @disable_auto_validations
end

Instance Method Details

#auto_generate_validations(property) ⇒ Object

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

Triggers that generate validator creation

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

:length => 20
    Setting the option :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

BigDecimal or Float type
    Using a Integer type causes a validates_numericality_of
    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


84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/dm-validations/auto_validate.rb', line 84

def auto_generate_validations(property)
  return if disabled_auto_validations? || skip_auto_validation_for?(property)

  # all auto-validations (aside from presence) should skip
  # validation when the value is nil
  opts = { :allow_nil => true }

  if property.options.key?(:validates)
    opts[:context] = property.options[:validates]
  end

  infer_presence_validation_for(property, opts.dup)
  infer_length_validation_for(property, opts.dup)
  infer_format_validation_for(property, opts.dup)
  infer_uniqueness_validation_for(property, opts.dup)
  infer_within_validation_for(property, opts.dup)
  infer_type_validation_for(property, opts.dup)
end

#disabled_auto_validations?TrueClass, FalseClass Also known as: auto_validations_disabled?

Checks whether auto validations are currently disabled (see disable_auto_validations method that takes a block)

Returns:

  • (TrueClass, FalseClass)

    true if auto validation is currently disabled



110
111
112
# File 'lib/dm-validations/auto_validate.rb', line 110

def disabled_auto_validations?
  @disable_auto_validations || false
end

#infer_format_validation_for(property, options) ⇒ Object



143
144
145
146
147
148
149
# File 'lib/dm-validations/auto_validate.rb', line 143

def infer_format_validation_for(property, options)
  return unless property.options.key?(:format)

  options[:with] = property.options[:format]

  validates_format_of property.name, options_with_message(options, property, :format)
end

#infer_length_validation_for(property, options) ⇒ Object



132
133
134
135
136
137
138
139
140
141
# File 'lib/dm-validations/auto_validate.rb', line 132

def infer_length_validation_for(property, options)
  return unless [ DataMapper::Property::String, DataMapper::Property::Text ].include?(property.class)

  case length = property.options.fetch(:length, DataMapper::Property::String::DEFAULT_LENGTH)
    when Range then options[:within]  = length
    else            options[:maximum] = length
  end

  validates_length_of property.name, options_with_message(options, property, :length)
end

#infer_presence_validation_for(property, options) ⇒ Object



126
127
128
129
130
# File 'lib/dm-validations/auto_validate.rb', line 126

def infer_presence_validation_for(property, options)
  return if skip_presence_validation?(property)

  validates_presence_of property.name, options_with_message(options, property, :presence)
end

#infer_type_validation_for(property, options) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/dm-validations/auto_validate.rb', line 172

def infer_type_validation_for(property, options)
  return if property.custom?

  if property.kind_of?(Property::Numeric)
    options[:gte] = property.min if property.min
    options[:lte] = property.max if property.max
  end

  if Integer == property.primitive
    options[:integer_only] = true

    validates_numericality_of property.name, options_with_message(options, property, :is_number)
  elsif BigDecimal == property.primitive || Float == property.primitive
    options[:precision] = property.precision
    options[:scale]     = property.scale

    validates_numericality_of property.name, options_with_message(options, property, :is_number)
  else
    # We only need this in the case we don't already
    # have a numeric validator, because otherwise
    # it will cause duplicate validation errors
    validates_primitive_type_of property.name, options_with_message(options, property, :is_primitive)
  end
end

#infer_uniqueness_validation_for(property, options) ⇒ Object



151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/dm-validations/auto_validate.rb', line 151

def infer_uniqueness_validation_for(property, options)
  return unless property.options.key?(:unique)

  case value = property.options[:unique]
    when Array, Symbol
      options[:scope] = Array(value)

      validates_uniqueness_of property.name, options_with_message(options, property, :is_unique)
    when TrueClass
      validates_uniqueness_of property.name, options_with_message(options, property, :is_unique)
  end
end

#infer_within_validation_for(property, options) ⇒ Object



164
165
166
167
168
169
170
# File 'lib/dm-validations/auto_validate.rb', line 164

def infer_within_validation_for(property, options)
  return unless property.options.key?(:set)

  options[:set] = property.options[:set]

  validates_within property.name, options_with_message(options, property, :within)
end

#options_with_message(base_options, property, validator_name) ⇒ Object

adds message for validator



12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/dm-validations/auto_validate.rb', line 12

def options_with_message(base_options, property, validator_name)
  options = base_options.clone
  opts    = property.options

  if opts.key?(:messages)
    options[:message] = opts[:messages][validator_name]
  elsif opts.key?(:message)
    options[:message] = opts[:message]
  end

  options
end

#skip_auto_validation_for?(property) ⇒ TrueClass, FalseClass

Checks whether or not property should be auto validated. It is the case for properties with :auto_validation option given and it’s value evaluates to true

Returns:

  • (TrueClass, FalseClass)

    true for properties with :auto_validation option that has positive value



122
123
124
# File 'lib/dm-validations/auto_validate.rb', line 122

def skip_auto_validation_for?(property)
  property.options.key?(:auto_validation) && !property.options[:auto_validation]
end

#without_auto_validations(&block) ⇒ Object

disables generation of validations for duration of given block



29
30
31
32
33
# File 'lib/dm-validations/auto_validate.rb', line 29

def without_auto_validations(&block)
  @disable_auto_validations = true
  block.call
  @disable_auto_validations = false
end