validates
- 1.0.0
- 1.1.6
- 1.2.6
- 2.0.3
- 2.1.0
- 2.2.1
- 2.3.8
- 3.0.0 (0)
- 3.0.9 (-4)
- 3.1.0 (14)
- 3.2.1 (1)
- 3.2.8 (0)
- 3.2.13 (0)
- 4.0.2 (38)
- 4.1.8 (5)
- 4.2.1 (5)
- 4.2.7 (0)
- 4.2.9 (0)
- 5.0.0.1 (0)
- 5.1.7 (0)
- 5.2.3 (-2)
- 6.0.0 (0)
- 6.1.3.1 (2)
- 6.1.7.7 (0)
- 7.0.0 (0)
- 7.1.3.2 (0)
- 7.1.3.4 (0)
- What's this?
validates(*attributes)
public
This method is a shortcut to all default validators and any custom validator classes ending in ‘Validator’. Note that Rails default validators can be overridden inside specific classes by creating custom validator classes in their place such as PresenceValidator.
Examples of using the default rails validators:
validates :terms, :acceptance => true validates :password, :confirmation => true validates :username, :exclusion => { :in => %w(admin superuser) } validates :email, :format => { :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :on => :create } validates :age, :inclusion => { :in => 0..9 } validates :first_name, :length => { :maximum => 30 } validates :age, :numericality => true validates :username, :presence => true validates :username, :uniqueness => true
The power of the validates method comes when using custom validators and default validators in one call for a given attribute e.g.
class EmailValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) record.errors[attribute] << (options[:message] || "is not an email") unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i end end class Person include ActiveModel::Validations attr_accessor :name, :email validates :name, :presence => true, :uniqueness => true, :length => { :maximum => 100 } validates :email, :presence => true, :email => true end
Validator classes may also exist within the class being validated allowing custom modules of validators to be included as needed e.g.
class Film include ActiveModel::Validations class TitleValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) record.errors[attribute] << "must start with 'the'" unless value =~ /\Athe/i end end validates :name, :title => true end
The validators hash can also handle regular expressions, ranges and arrays:
validates :email, :format => /@/ validates :gender, :inclusion => %w(male female) validates :password, :length => 6..20
Finally, the options :if, :unless, :on, :allow_blank and :allow_nil can be given to one specific validator:
validates :password, :presence => { :if => :password_required? }, :confirmation => true
Or to all at the same time:
validates :password, :presence => true, :confirmation => true, :if => :password_required?
case-insensitive uniqueness
For case-insensitive uniqueness:
validate :username, :uniqueness => {:case_sensitive => false}
multiple attributes with the same validations
You can list multiple attributes if they share the same validations
validates :title, :body, :presence => true
sending the attributes as an array will return an error
validates [:title, :body], :presence => true #=> ArgumentError: Attribute names must be symbols
uniqueness
You can scope uniqueness as well
validates :user_name, :presence => true, :uniqueness => {:scope => :account_id} # the old way validates_uniqueness_of :user_name, :scope => :account_id
Changing the Message
For Change the default message:
Code example
validates :invoice_number, :presence => {:message => 'The invoice number must be informed.'}
Custom validator with i18n support
Here is modified EmailValidator from the example above:
class EmailValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) record.errors.add(attribute, options[:message] || :email) unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i end end
And locale:
en: activerecord: errors: messages: email: "is not an email"
validating a database column acceptance
accept option should be set to true if you are validating a database column, since the attribute is typecast from “1” to true before validation
validates :terms, acceptance: { allow_nil: false, accept: true }
Validate number
option like :greater_than still supported
use like this
Code example
validates :position, :presence => true, :numericality => {:greater_than => 0}
Common Validator options
Most validators will support all of the following common options: (Through ActiveModel::Errors::CALLBACK_OPTIONS (http://apidock.com/rails/ActiveModel/Errors))
-
:if
-
:unless
-
:allow_blank
-
:allow_nil
Example of conditions using
f.e.
validates :number, :presence => { :if => :quota_file? } def self.quota_file? quota_file? end
attributes that have the same names as options
For reasons that are beyond my comprehension, this piece of code
class Working include ActiveModel::Validations attr_accessor :format validates :format, :presence => true, :format => { :with => /\AWorking/ } end
works (NOTE: it has an attribute that has the same name of an option), while this
class NotWorking < ActiveRecord::Base validates :format, :presence => true, :format => { :with => /\ANot Working/ } end
does not (assuming that you have a legacy db in which you can’t change the names of the columns). It throws an ArgumentError at you. However, a crude hack is to add an explicit accessor to the :format method, like this
class WorkingAgain < ActiveRecord::Base validates :format, :presence => true, :format => { :with => /\AWorking again/ } def format read_attribute(:format) end end
Any explanation is welcome.