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 :username, absence: true 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
The power of the validates method comes when using custom validators and default validators in one call for a given attribute.
class EmailValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) record.errors.add attribute, (options[:message] || "is not an email") unless /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i.match?(value) end end class Person include ActiveModel::Validations attr_accessor :name, :email validates :name, presence: 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.
class Film include ActiveModel::Validations class TitleValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) record.errors.add attribute, "must start with 'the'" unless /\Athe/i.match?(value) end end validates :name, title: true end
Additionally validator classes may be in another namespace and still used within any class.
validates :name, :'film/title' => true
The validators hash can also handle regular expressions, ranges, arrays and strings in shortcut form.
validates :email, format: /@/ validates :role, inclusion: %w(admin contributor) validates :password, length: 6..20
When using shortcut form, ranges and arrays are passed to your validator’s initializer as options[:in] while other types including regular expressions and strings are passed as options[:with].
There is also a list of options that could be used along with validators:
-
:on - Specifies the contexts where this validation is active. Runs in all validation contexts by default nil. You can pass a symbol or an array of symbols. (e.g. on: :create or on: :custom_validation_context or on: [:create, :custom_validation_context])
-
:if - Specifies a method, proc, or string to call to determine if the validation should occur (e.g. if: :allow_validation, or if: Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.
-
:unless - Specifies a method, proc, or string to call to determine if the validation should not occur (e.g. unless: :skip_validation, or unless: Proc.new { |user| user.signup_step <= 2 }). The method, proc, or string should return or evaluate to a true or false value.
-
:allow_nil - Skip validation if the attribute is nil.
-
:allow_blank - Skip validation if the attribute is blank.
-
:strict - If the :strict option is set to true will raise ActiveModel::StrictValidationFailed instead of adding the error. :strict option can also be set to any other exception.
Example:
validates :password, presence: true, confirmation: true, if: :password_required? validates :token, length: { is: 24 }, strict: TokenLengthException
Finally, the options :if, :unless, :on, :allow_blank, :allow_nil, :strict and :message can be given to one specific validator, as a hash:
validates :password, presence: { if: :password_required?, message: 'is forgotten.' }, confirmation: true
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.