Note:
In case the attribute is a boolean one, you cannot make use of the usual presence validation (the attribute would not be valid for a false value). You can get this done by using an inclusion validation:
validates :attribute, inclusion:[true,false]
Custom validations
You can add your own validations adding new classes inheriting from ActiveModel::Validator or from ActiveModel::EachValidator. Both methods are similar but they work in a slightly different ways:
ActiveModel::Validator and validates_with
Implement the validate method which takes a record as an argument and performs the validation on it. Then use validates_with with the class on the model.
# app/validators/starts_with_a_validator.rbclassStartsWithAValidator<ActiveModel::Validatordefvalidate(record)unless record.name.starts_with?'A'
record.errors[:name]<<'Need a name starting with A please!'endendendclassPerson<ApplicationRecord
validates_with StartsWithAValidatorend
ActiveModel::EachValidator and validate
If you prefer to use your new validator using the common validate method on a single param, create a class inheriting from ActiveModel::EachValidator and implement the validate_each method which takes three arguments: record, attribute, and value:
classEmailValidator<ActiveModel::EachValidatordefvalidate_each(record, attribute, value)unless value =~/\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
record.errors[attribute]<<(options[:message]||'is not an email')endendendclassPerson<ApplicationRecord
validates :email, presence:true, email:trueend
You can also define a constant and set its value to a regular expression and pass it to the with: option. This might be more convenient for really complex regular expressions
Besides :only_integer, this helper also accepts the following options to add constraints to acceptable values:
:greater_than - Specifies the value must be greater than the supplied value. The default error message for this option is "must be greater than %{count}".
:greater_than_or_equal_to - Specifies the value must be greater than or equal to the supplied value. The default error message for this option is "must be greater than or equal to %{count}".
:equal_to - Specifies the value must be equal to the supplied value. The default error message for this option is "must be equal to %{count}".
:less_than - Specifies the value must be less than the supplied value. The default error message for this option is "must be less than %{count}".
:less_than_or_equal_to - Specifies the value must be less than or equal to the supplied value. The default error message for this option is "must be less than or equal to %{count}".
:other_than - Specifies the value must be other than the supplied value. The default error message for this option is "must be other than %{count}".
:odd - Specifies the value must be an odd number if set to true. The default error message for this option is "must be odd".
:even - Specifies the value must be an even number if set to true. The default error message for this option is "must be even".
By default, numericality doesn't allow nil values. You can use allow_nil: true option to permit it.
Grouping validation
Sometimes it is useful to have multiple validations use one condition. It can be easily achieved using with_options.
There is a :scope option that you can use to specify one or more attributes that are used to limit the uniqueness check:
classHoliday<ApplicationRecord
validates :name, uniqueness:{ scope::year,
message:"should happen once per year"}end
There is also a :case_sensitive option that you can use to define whether the uniqueness constraint will be case sensitive or not. This option defaults to true.
You should use this when you have two text fields that should receive exactly the same content. For example, you may want to confirm an email address or a password. This validation creates a virtual attribute whose name is the name of the field that has to be confirmed with _confirmation appended.
The :on option lets you specify when the validation should happen.
The default behavior for all the built-in validation helpers is to be run on save (both when you're creating a new record and when you're updating it).
classPerson<ApplicationRecord# it will be possible to update email with a duplicated value
validates :email, uniqueness:true, on::create# it will be possible to create the record with a non-numerical age
validates :age, numericality:true, on::update# the default (validates on both create and update)
validates :name, presence:trueend