All of the following validations are defined in the class scope of the model that you’re interested in validating. They offer a more declarative way of specifying when the model is valid and when it is not. It is recommended to use these over the low-level calls to validate and validate_on_create when possible.

Methods
Constants
DEFAULT_VALIDATION_OPTIONS = { :on => :save, :allow_nil => false, :message => nil
DEFAULT_SIZE_VALIDATION_OPTIONS = DEFAULT_VALIDATION_OPTIONS.merge( :too_long => ActiveRecord::Errors.default_error_messages[:too_long], :too_short => ActiveRecord::Errors.default_error_messages[:too_short], :wrong_length => ActiveRecord::Errors.default_error_messages[:wrong_length]
ALL_RANGE_OPTIONS = [ :is, :within, :in, :minimum, :maximum ].freeze
Public Instance methods
validate(*methods, &block)
     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 214
214:       def validate(*methods, &block)
215:         methods << block if block_given?
216:         write_inheritable_set(:validate, methods)
217:       end
validate_on_create(*methods, &block)
     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 219
219:       def validate_on_create(*methods, &block)
220:         methods << block if block_given?
221:         write_inheritable_set(:validate_on_create, methods)
222:       end
validate_on_update(*methods, &block)
     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 224
224:       def validate_on_update(*methods, &block)
225:         methods << block if block_given?
226:         write_inheritable_set(:validate_on_update, methods)
227:       end
validates_acceptance_of(*attr_names)

Encapsulates the pattern of wanting to validate the acceptance of a terms of service check box (or similar agreement). Example:

  class Person < ActiveRecord::Base
    validates_acceptance_of :terms_of_service
    validates_acceptance_of :eula, :message => "must be abided"
  end

The terms_of_service attribute is entirely virtual. No database column is needed. This check is performed only if terms_of_service is not nil and by default on save.

Configuration options:

  • message - A custom error message (default is: "can’t be empty")
  • on - Specifies when this validation is active (default is :save, other options :create, :update)
  • accept - Specifies value that is considered accepted. The default value is a string "1", which

makes it easy to relate to an HTML checkbox.

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 301
301:       def validates_acceptance_of(*attr_names)
302:         configuration = { :message => ActiveRecord::Errors.default_error_messages[:accepted], :on => :save, :allow_nil => true, :accept => "1" }
303:         configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
304: 
305:         attr_accessor *attr_names
306:         
307:         validates_each(attr_names,configuration) do |record, attr_name, value|
308:           record.errors.add(attr_name, configuration[:message]) unless value == configuration[:accept]
309:         end
310:       end
validates_associated(*attr_names)

Validates whether the associated object or objects are all themselves valid. Works with any kind of association.

  class Book < ActiveRecord::Base
    has_many :pages
    belongs_to :library

    validates_associated :pages, :library
  end

Warning: If, after the above definition, you then wrote:

  class Page < ActiveRecord::Base
    belongs_to :book

    validates_associated :book
  end

this would specify a circular dependency and cause infinite recursion. The Rails team recommends against this practice.

Configuration options:

  • on Specifies when this validation is active (default is :save, other options :create, :update)
     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 494
494:       def validates_associated(*attr_names)
495:         configuration = { :message => ActiveRecord::Errors.default_error_messages[:invalid], :on => :save }
496:         configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
497: 
498:         validates_each(attr_names, configuration) do |record, attr_name, value|
499:           record.errors.add(attr_name, configuration[:message]) unless 
500:             (value.is_a?(Array) ? value : [value]).inject(true) { |memo, r| (r.nil? or r.valid?) and memo }
501:         end
502:       end
validates_confirmation_of(*attr_names)

Encapsulates the pattern of wanting to validate a password or email address field with a confirmation. Example:

  Model:
    class Person < ActiveRecord::Base
      validates_confirmation_of :user_name, :password
      validates_confirmation_of :email_address, :message => "should match confirmation"
    end

  View:
    <%= password_field "person", "password" %>
    <%= password_field "person", "password_confirmation" %>

The person has to already have a password attribute (a column in the people table), but the password_confirmation is virtual. It exists only as an in-memory variable for validating the password. This check is performed only if password_confirmation is not nil and by default on save.

Configuration options:

  • message - A custom error message (default is: "doesn’t match confirmation")
  • on - Specifies when this validation is active (default is :save, other options :create, :update)
     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 273
273:       def validates_confirmation_of(*attr_names)
274:         configuration = { :message => ActiveRecord::Errors.default_error_messages[:confirmation], :on => :save }
275:         configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
276: 
277:         attr_accessor *(attr_names.map { |n| "#{n}_confirmation" })
278:         
279:         validates_each(attr_names, configuration) do |record, attr_name, value|
280:           record.errors.add(attr_name, configuration[:message]) unless record.send("#{attr_name}_confirmation").nil? or value == record.send("#{attr_name}_confirmation")
281:         end
282:       end
validates_each(*attrs) {|record, attr, value| ...}

Validates each attribute against a block.

  class Person < ActiveRecord::Base
    validates_each :first_name, :last_name do |record, attr|
      record.errors.add attr, 'starts with z.' if attr[0] == ?z
    end
  end

Options:

  • on - Specifies when this validation is active (default is :save, other options :create, :update)
  • allow_nil - Skip validation if attribute is nil.
     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 240
240:       def validates_each(*attrs)
241:         options = attrs.last.is_a?(Hash) ? attrs.pop.symbolize_keys : {}
242:         attrs = attrs.flatten
243: 
244:         # Declare the validation.
245:         send(validation_method(options[:on] || :save)) do |record|
246:           attrs.each do |attr|
247:             value = record.send(attr)
248:             next if value.nil? && options[:allow_nil]
249:             yield record, attr, value
250:           end
251:         end
252:       end
validates_format_of(*attr_names)

Validates whether the value of the specified attribute is of the correct form by matching it against the regular expression provided.

  class Person < ActiveRecord::Base
    validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/, :on => :create
  end

A regular expression must be provided or else an exception will be raised.

Configuration options:

  • message - A custom error message (default is: "is invalid")
  • with - The regular expression used to validate the format with (note: must be supplied!)
  • on Specifies when this validation is active (default is :save, other options :create, :update)
     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 438
438:       def validates_format_of(*attr_names)
439:         configuration = { :message => ActiveRecord::Errors.default_error_messages[:invalid], :on => :save, :with => nil }
440:         configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
441: 
442:         raise(ArgumentError, "A regular expression must be supplied as the :with option of the configuration hash") unless configuration[:with].is_a?(Regexp)
443: 
444:         validates_each(attr_names, configuration) do |record, attr_name, value|
445:           record.errors.add(attr_name, configuration[:message]) unless value.to_s =~ configuration[:with]
446:         end
447:       end
validates_inclusion_of(*attr_names)

Validates whether the value of the specified attribute is available in a particular enumerable object.

  class Person < ActiveRecord::Base
    validates_inclusion_of :gender, :in=>%w( m f ), :message=>"woah! what are you then!??!!"
    validates_inclusion_of :age, :in=>0..99
  end

Configuration options:

  • in - An enumerable object of available items
  • message - Specifies a customer error message (default is: "is not included in the list")
  • allow_nil - If set to true, skips this validation if the attribute is null (default is: false)
     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 460
460:       def validates_inclusion_of(*attr_names)
461:         configuration = { :message => ActiveRecord::Errors.default_error_messages[:inclusion], :on => :save }
462:         configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
463:  
464:         enum = configuration[:in] || configuration[:within]
465:  
466:         raise(ArgumentError, "An object with the method include? is required must be supplied as the :in option of the configuration hash") unless enum.respond_to?("include?")
467: 
468:         validates_each(attr_names, configuration) do |record, attr_name, value|
469:           record.errors.add(attr_name, configuration[:message]) unless enum.include?(value)
470:         end
471:       end
validates_length_of(*attrs)

Validates that the specified attribute matches the length restrictions supplied. Only one option can be used at a time:

  class Person < ActiveRecord::Base
    validates_length_of :first_name, :maximum=>30
    validates_length_of :last_name, :maximum=>30, :message=>"less than %d if you don't mind"
    validates_length_of :fax, :in => 7..32, :allow_nil => true
    validates_length_of :user_name, :within => 6..20, :too_long => "pick a shorter name", :too_short => "pick a longer name"
    validates_length_of :fav_bra_size, :minimum=>1, :too_short=>"please enter at least %d character"
    validates_length_of :smurf_leader, :is=>4, :message=>"papa is spelled with %d characters... don't play me."
  end

Configuration options:

  • minimum - The minimum size of the attribute
  • maximum - The maximum size of the attribute
  • is - The exact size of the attribute
  • within - A range specifying the minimum and maximum size of the attribute
  • in - A synonym(or alias) for :within
  • allow_nil - Attribute may be nil; skip validation.
  • too_long - The error message if the attribute goes over the maximum (default is: "is too long (max is %d characters)")
  • too_short - The error message if the attribute goes under the minimum (default is: "is too short (min is %d characters)")
  • wrong_length - The error message if using the :is method and the attribute is the wrong size (default is: "is the wrong length (should be %d characters)")
  • message - The error message to use for a :minimum, :maximum, or :is violation. An alias of the appropriate too_long/too_short/wrong_length message
  • on - Specifies when this validation is active (default is :save, other options :create, :update)
This method is also aliased as validates_size_of
     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 354
354:       def validates_length_of(*attrs)
355:         # Merge given options with defaults.
356:         options = DEFAULT_SIZE_VALIDATION_OPTIONS.dup
357:         options.update(attrs.pop.symbolize_keys) if attrs.last.is_a?(Hash)
358: 
359:         # Ensure that one and only one range option is specified.
360:         range_options = ALL_RANGE_OPTIONS & options.keys
361:         case range_options.size
362:           when 0
363:             raise ArgumentError, 'Range unspecified.  Specify the :within, :maximum, :minimum, or :is option.'
364:           when 1
365:             # Valid number of options; do nothing.
366:           else
367:             raise ArgumentError, 'Too many range options specified.  Choose only one.'
368:         end
369: 
370:         # Get range option and value.
371:         option = range_options.first
372:         option_value = options[range_options.first]
373: 
374:         # Declare different validations per option.
375:         
376:         validity_checks = { :is => "==", :minimum => ">=", :maximum => "<=" }
377:         message_options = { :is => :wrong_length, :minimum => :too_short, :maximum => :too_long }
378: 
379:         case option
380:         when :within, :in
381:           raise ArgumentError, ':within must be a Range' unless option_value.is_a?(Range) # '
382:           validates_length_of attrs, :minimum => option_value.begin, :allow_nil => options[:allow_nil]
383:           validates_length_of attrs, :maximum => option_value.end, :allow_nil => options[:allow_nil]
384:         when :is, :minimum, :maximum
385:           raise ArgumentError, ":#{option} must be a nonnegative Integer" unless option_value.is_a?(Integer) and option_value >= 0 # '
386:           message = options[:message] || options[message_options[option]]
387:           message = (message % option_value) rescue message
388:           validates_each(attrs, options) do |record, attr, value|
389:             record.errors.add(attr, message) if value.nil? or !value.size.method(validity_checks[option])[option_value]
390:           end
391:         end
392:       end
validates_numericality_of(*attr_names)

Validates whether the value of the specified attribute is numeric by trying to convert it to a float with Kernel.Float (if integer is false) or applying it to the regular expression /^[+\-]?\d+$/ (if integer is set to true).

  class Person < ActiveRecord::Base
    validates_numericality_of :value, :on => :create
  end

Configuration options:

  • message - A custom error message (default is: "is not a number")
  • on Specifies when this validation is active (default is :save, other options :create, :update)
  • only_integer Specifies whether the value has to be an integer, e.g. an integral value (default is false)
  • allow_nil Skip validation if attribute is nil (default is false). Notice that for fixnum and float columsn empty strings are converted to nil
     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 517
517:       def validates_numericality_of(*attr_names)
518:         configuration = { :message => ActiveRecord::Errors.default_error_messages[:not_a_number], :on => :save,
519:                            :only_integer => false, :allow_nil => false }
520:         configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
521: 
522:         if configuration[:only_integer]
523:           validates_each(attr_names,configuration) do |record, attr_name,value|
524:             record.errors.add(attr_name, configuration[:message]) unless record.send("#{attr_name}_before_type_cast").to_s =~ /^[+-]?\d+$/
525:           end
526:         else
527:           validates_each(attr_names,configuration) do |record, attr_name,value|
528:             begin
529:               Kernel.Float(record.send("#{attr_name}_before_type_cast").to_s)
530:             rescue ArgumentError, TypeError
531:               record.errors.add(attr_name, configuration[:message])
532:             end
533:           end
534:         end
535:       end
validates_presence_of(*attr_names)

Validates that the specified attributes are neither nil nor empty. Happens by default on save.

Configuration options:

  • message - A custom error message (default is: "has already been taken")
  • on - Specifies when this validation is active (default is :save, other options :create, :update)
     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 317
317:       def validates_presence_of(*attr_names)
318:         configuration = { :message => ActiveRecord::Errors.default_error_messages[:empty], :on => :save }
319:         configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
320: 
321:         # can't use validates_each here, because it cannot cope with non-existant attributes,
322:         # while errors.add_on_empty can 
323:         attr_names.each do |attr_name|
324:           send(validation_method(configuration[:on])) do |record|
325:             record.errors.add_on_empty(attr_name,configuration[:message])
326:           end
327:         end
328:       end
validates_size_of(*attrs)
validates_uniqueness_of(*attr_names)

Validates whether the value of the specified attributes are unique across the system. Useful for making sure that only one user can be named "davidhh".

  class Person < ActiveRecord::Base
    validates_uniqueness_of :user_name, :scope => "account_id"
  end

When the record is created, a check is performed to make sure that no record exist in the database with the given value for the specified attribute (that maps to a column). When the record is updated, the same check is made but disregarding the record itself.

Configuration options:

  • message - Specifies a custom error message (default is: "has already been taken")
  • scope - Ensures that the uniqueness is restricted to a condition of "scope = record.scope"
     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 410
410:       def validates_uniqueness_of(*attr_names)
411:         configuration = { :message => ActiveRecord::Errors.default_error_messages[:taken] }
412:         configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
413: 
414:         if scope = configuration[:scope]
415:           validates_each(attr_names,configuration) do |record, attr_name, value|
416:             record.errors.add(attr_name, configuration[:message]) if record.class.find_first(record.new_record? ? ["#{attr_name} = ? AND #{scope} = ?", record.send(attr_name), record.send(scope)] : ["#{attr_name} = ? AND #{record.class.primary_key} <> ? AND #{scope} = ?", record.send(attr_name), record.send(:id), record.send(scope)])
417:           end
418:         else
419:           validates_each(attr_names,configuration) do |record, attr_name, value|
420:             record.errors.add(attr_name, configuration[:message]) if record.class.find_first(record.new_record? ? ["#{attr_name} = ?", record.send(attr_name)] : ["#{attr_name} = ? AND #{record.class.primary_key} <> ?", record.send(attr_name), record.send(:id) ] )
421:           end
422:         end
423:       end