Method: ActiveModel::Validations::ClassMethods#validates
- Defined in:
- lib/active_model/validations/validates.rb
#validates(*attributes) ⇒ Object
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, ([: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 defaultnil. You can pass a symbol or an array of symbols. (e.g.on: :createoron: :custom_validation_contextoron: [:create, :custom_validation_context]) -
:except_on- Specifies the contexts where this validation is not active. Runs in all validation contexts by defaultnil. You can pass a symbol or an array of symbols. (e.g.except: :createorexcept_on: :custom_validation_contextorexcept_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, orif: Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to atrueorfalsevalue. -
:unless- Specifies a method, proc, or string to call to determine if the validation should not occur (e.g.unless: :skip_validation, orunless: Proc.new { |user| user.signup_step <= 2 }). The method, proc, or string should return or evaluate to atrueorfalsevalue. -
:allow_nil- Skip validation if the attribute isnil. -
:allow_blank- Skip validation if the attribute is blank. -
:strict- If the:strictoption is set to true will raise ActiveModel::StrictValidationFailed instead of adding the error.:strictoption 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
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/active_model/validations/validates.rb', line 111 def validates(*attributes) defaults = attributes..dup validations = defaults.slice!(*_validates_default_keys) raise ArgumentError, "You need to supply at least one attribute" if attributes.empty? raise ArgumentError, "You need to supply at least one validation" if validations.empty? defaults[:attributes] = attributes validations.each do |key, | key = "#{key.to_s.camelize}Validator" begin validator = const_get(key) rescue NameError raise ArgumentError, "Unknown validator: '#{key}'" end next unless validates_with(validator, defaults.merge(())) end end |