Rails Validations Cheatsheet
Builtin Validators
class Player < ApplicationRecord
validates :terms_of_service, acceptance: true
validates :name, :address, presence: true
validates :password, confirmation: true
# numericality validation does not allow nil value
# use allow_nil: true to permit it
validates :points, numericality: true
validates :games_played, numericality: { only_integer: true }
# other options:
# :greater_than
# :greater_than_or_equal_to
# :equal_to
# :less_than
# :less_than_or_equal_to
# :other_than
# :odd
# :even
end
Conditional Validations
class User < ApplicationRecord
validates :password, confirmation: true,
unless: Proc.new { |a| a.password.blank? }
validates :name, if: :active?
# Group similar conditional validation
with_options if: :is_admin? do |admin|
admin.validates :password, length: { minimum: 10 }
admin.validates :email, presence: true
end
end
Custom validators
These custom validators should be placed in app/validators
Validate object as a whole
class MyValidator < ActiveModel::Validator
def validate(record)
unless record.name.starts_with? 'X'
record.errors[:name] << 'Need a name starting with X please!'
end
end
end
class Person < ActiveRecord::Base
validates_with MyValidator
end
Validate individual attribute
class EmailValidator < ActiveModel::EachValidator
def validate_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")
end
end
end
class Person < ActiveRecord::Base
validates :email, presence: true, email: true
end
Custom validation methods
class Event < ApplicationRecord
validate :start_date_must_be_before_end_date
private
def start_date_must_be_before_end_date
if start_date > end_date
errors.add(:base, "start date must be before end date")
end
end
end