Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Back to Basics: Validations in Rails
- ```bash
- rails new basics --skip-bootsnap --skip-bundle --skip-action-cable --skip-active-storage --skip-action-mailer --skip-yarn --skip-sprockets --skip-turbolinks --skip-coffee --skip-javascript --database=postgresql
- ```
- ```bash
- rails db:setup db:migrate
- ```
- ## Models
- ```bash
- rails g model User name email bio:text age:integer states_visited:array
- ```
- ## Basics of rails validations
- ### presence
- ```ruby
- validates :name, presence: true
- validates_presence_of :name
- ```
- ### chaining
- ```ruby
- validates :first_name, :last_name, presence: true
- ```
- ### multiple
- ```ruby
- validates :name, presence: true, length: { minimum: 2 }
- validates :name, presence: true, length: { minimum: 2, maximum: 255 }
- validates :name, presence: true, length: { in: 2..255 }
- ```
- ### format
- ```ruby
- EMAIL_REGEX = /\A\S+@.+\.\S+\z/
- validates :email, format: { with: EMAIL_REGEX }
- ```
- ### numericality
- ```ruby
- validates :age, numericality: { only_integer: true }
- validates :age, numericality: { only_integer: true, greater_than: 0, less_than: 1000 }
- validates :age, numericality: { only_integer: true, greater_than: 0, less_than: 1000, other_than: 69 }
- ```
- ### uniqueness
- ```ruby
- validates :email, uniqueness: true
- validates :email, uniqueness: { case_sensitive: false }
- validates :email, uniqueness: { scope: :name, case_sensitive: false }
- ```
- ### options
- ```ruby
- validates :age, numericality: { only_integer: true }, allow_nil: true
- validates :name, length: { in: 2..255 }, allow_blank: true
- validates :name, length: { in: 2..255 }, allow_blank: true, on: :update
- validates :email, uniqueness: true, if: :email_changed?
- validates :email, uniqueness: true, unless: -> { Rails.env.test? }
- ```
- ## Custom validations
- ### validate
- ```ruby
- validate :states_visited_has_no_empty_elements
- def states_visited_has_no_empty_elements
- return unless states_visited.include?(nil) || states_visited.include?('')
- errors.add(:states_visited, 'cannot contain nil or an empty string')
- end
- ```
- ### ActiveModel::Validator
- ```ruby
- class ReadOnlyValidator < ActiveModel::Validtor
- def validate(record)
- record.errors.add(:base, 'The system is read only') if ENV['READ_ONLY']
- end
- end
- class User < ApplicationRecord
- validates_with ReadOnlyValidator
- end
- ```
- ### ActiveModel::EachValidator
- ```ruby
- class EmailValidator < ActiveModel::EachValidator
- EMAIL_REGEX = /\A\S+@.+\.\S+\z/
- def validate_each(record, attribute, value)
- return if value.match? EMAIL_REGEX
- record.errors[attribute] << (options[:message] || 'format is invalid')
- end
- end
- validates :email, email: true
- validates :email, email: true, message: 'needs to be a valid email address'
- ```
- ## Validation Contexts
- ### on:
- ```ruby
- validates :bio, length: { minimum: 1 }, on: :admin
- validates :bio, length: { minimum: 3 }, on: :user
- validates :bio, length: { minimum: 3 }, on: [:user, :admin]
- u = User.new(bio: 'a')
- u.valid?(:admin)
- u.valid?(:user)
- ```
- Can be used with `valid?`, `invalid?`, and `save`.
- ## ActiveModel::Errors
- ### .errors
- ```ruby
- u = User.new(bio: 'hello!', name: 'Bob')
- u.errors
- u.valid?
- u.errors
- ```
- ### .errors[]
- ### .errors[:attr].add / .errors[:attr] <<
- ### .errors[:base]
- ### .errors.messages
- ### .errors.details
- ### .errors.full_messages
- ### .errors.clear
Add Comment
Please, Sign In to add comment