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 211
211:       def validate(*methods, &block)
212:         methods << block if block_given?
213:         write_inheritable_set(:validate, methods)
214:       end
validate_on_create(*methods, &block)
     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 216
216:       def validate_on_create(*methods, &block)
217:         methods << block if block_given?
218:         write_inheritable_set(:validate_on_create, methods)
219:       end
validate_on_update(*methods, &block)
     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 221
221:       def validate_on_update(*methods, &block)
222:         methods << block if block_given?
223:         write_inheritable_set(:validate_on_update, methods)
224:       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)

NOTE: The agreement is considered valid if it’s set to the string "1". This makes it easy to relate it to an HTML checkbox.

     # File vendor/rails/activerecord/lib/active_record/validations.rb, line 296
296:       def validates_acceptance_of(*attr_names)
297:         configuration = { :message => ActiveRecord::Errors.default_error_messages[:accepted], :on => :save, :allow_nil => true }
298:         configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
299: 
300:         attr_accessor *attr_names
301:         
302:         validates_each(attr_names,configuration) do |record, attr_name, value|
303:           record.errors.add(attr_name, configuration[:message]) unless value == "1"       
304:         end
305:       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 501
501:       def validates_associated(*attr_names)
502:         configuration = { :message => ActiveRecord::Errors.default_error_messages[:invalid], :on => :save }
503:         configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
504: 
505:         validates_each(attr_names, configuration) do |record, attr_name, value|
506:           record.errors.add(attr_name, configuration[:message]) unless 
507:             (value.is_a?(Array) ? value : [value]).inject(true) { |memo, r| (r.nil? or r.valid?) and memo }
508:         end
509:       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 270
270:       def validates_confirmation_of(*attr_names)
271:         configuration = { :message => ActiveRecord::Errors.default_error_messages[:confirmation], :on => :save }
272:         configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
273: 
274:         attr_accessor *(attr_names.map { |n| "#{n}_confirmation" })
275:         
276:         validates_each(attr_names, configuration) do |record, attr_name, value|
277:           record.errors.add(attr_name, configuration[:message]) unless record.send("#{attr_name}_confirmation").nil? or value == record.send("#{attr_name}_confirmation")
278:         end
279:       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 237
237:       def validates_each(*attrs)
238:         options = attrs.last.is_a?(Hash) ? attrs.pop.symbolize_keys : {}
239:         attrs = attrs.flatten
240: 
241:         # Declare the validation.
242:         send(validation_method(options[:on] || :save)) do |record|
243:           attrs.each do |attr|
244:             value = record.send(attr)
245:             next if value.nil? && options[:allow_nil]
246:             yield record, attr, value
247:           end
248:         end
249:       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 445
445:       def validates_format_of(*attr_names)
446:         configuration = { :message => ActiveRecord::Errors.default_error_messages[:invalid], :on => :save, :with => nil }
447:         configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
448: 
449:         raise(ArgumentError, "A regular expression must be supplied as the :with option of the configuration hash") unless configuration[:with].is_a?(Regexp)
450: 
451:         validates_each(attr_names, configuration) do |record, attr_name, value|
452:           record.errors.add(attr_name, configuration[:message]) unless value.to_s =~ configuration[:with]
453:         end
454:       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 467
467:       def validates_inclusion_of(*attr_names)
468:         configuration = { :message => ActiveRecord::Errors.default_error_messages[:inclusion], :on => :save }
469:         configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
470:  
471:         enum = configuration[:in] || configuration[:within]
472:  
473:         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?")
474: 
475:         validates_each(attr_names, configuration) do |record, attr_name, value|
476:           record.errors.add(attr_name, configuration[:message]) unless enum.include?(value)
477:         end
478:       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 349
349:       def validates_length_of(*attrs)
350:         # Merge given options with defaults.
351:         options = DEFAULT_SIZE_VALIDATION_OPTIONS.dup
352:         options.update(attrs.pop.symbolize_keys) if attrs.last.is_a?(Hash)
353: 
354:         # Ensure that one and only one range option is specified.
355:         range_options = ALL_RANGE_OPTIONS & options.keys
356:         case range_options.size
357:         when 0
358:           raise ArgumentError, 'Range unspecified.  Specify the :within, :maximum, :minimum, or :is option.'
359:         when 1
360:           # Valid number of options; do nothing.
361:         else
362:           raise ArgumentError, 'Too many range options specified.  Choose only one.'
363:         end
364: 
365:         # Get range option and value.
366:         option = range_options.first
367:         option_value = options[range_options.first]
368: 
369:         # Declare different validations per option.
370:         case range_options.first
371:         when :within, :in
372:           raise ArgumentError, ':within must be a Range' unless option_value.is_a?(Range)
373:           validates_each(attrs, options) do |record, attr|
374:             next if record.send(attr).nil? and options[:allow_nil]
375:             record.errors.add_on_boundary_breaking(attr, option_value, options[:too_long], options[:too_short])
376:           end
377:         when :is
378:           raise ArgumentError, ':is must be a nonnegative Integer' unless option_value.is_a?(Integer) and option_value >= 0
379:           message = options[:message] || options[:wrong_length]
380:           message = (message % option_value) rescue message
381:           validates_each(attrs, options) do |record, attr, value|
382:             record.errors.add(attr, message) if value.nil? or value.size != option_value
383:           end
384:         when :minimum
385:           raise ArgumentError, ':minimum must be a nonnegative Integer' unless option_value.is_a?(Integer) and option_value >= 0
386:           message = options[:message] || options[:too_short]
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 < option_value
390:           end
391:         when :maximum
392:           raise ArgumentError, ':maximum must be a nonnegative Integer' unless option_value.is_a?(Integer) and option_value >= 0
393:           message = options[:message] || options[:too_long]
394:           message = (message % option_value) rescue message
395:           validates_each(attrs, options) do |record, attr, value|
396:             record.errors.add(attr, message) if value.nil? or value.size > option_value
397:           end
398:         end
399:       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 524
524:       def validates_numericality_of(*attr_names)
525:         configuration = { :message => ActiveRecord::Errors.default_error_messages[:not_a_number], :on => :save,
526:                            :only_integer => false, :allow_nil => false }
527:         configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
528: 
529:         if configuration[:only_integer]
530:           validates_each(attr_names,configuration) do |record, attr_name,value|
531:             record.errors.add(attr_name, configuration[:message]) unless record.send("#{attr_name}_before_type_cast").to_s =~ /^[+-]?\d+$/
532:           end
533:         else
534:           validates_each(attr_names,configuration) do |record, attr_name,value|
535:             begin
536:               Kernel.Float(record.send("#{attr_name}_before_type_cast").to_s)
537:             rescue ArgumentError, TypeError
538:               record.errors.add(attr_name, configuration[:message])
539:             end
540:           end
541:         end
542:       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 312
312:       def validates_presence_of(*attr_names)
313:         configuration = { :message => ActiveRecord::Errors.default_error_messages[:empty], :on => :save }
314:         configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
315: 
316:         # can't use validates_each here, because it cannot cope with non-existant attributes,
317:         # while errors.add_on_empty can 
318:         attr_names.each do |attr_name|
319:           send(validation_method(configuration[:on])) do |record|
320:             record.errors.add_on_empty(attr_name,configuration[:message])
321:           end
322:         end
323:       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 417
417:       def validates_uniqueness_of(*attr_names)
418:         configuration = { :message => ActiveRecord::Errors.default_error_messages[:taken] }
419:         configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
420: 
421:         if scope = configuration[:scope]
422:           validates_each(attr_names,configuration) do |record, attr_name, value|
423:             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)])
424:           end
425:         else
426:           validates_each(attr_names,configuration) do |record, attr_name, value|
427:             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) ] )
428:           end
429:         end
430:       end