Валидация — это инструмент, который проверяет корректность данных объекта перед сохранением в базу данных. Если данные не проходят валидацию, то объект не сохраняется. Функционал валидаций используют, чтобы поддерживать целостность данных и предотвращать возможные ошибки в проекте.
Как работает валидация в Rails
Валидация в Ruby on Rails — это специальный метод в классе модели Active Record. Этот метод вызывается, когда мы пытаемся сохранить объект в базе данных. При неудаче метод валидации возвращает false, и объект не сохраняется.
Ниже приведен пример базовой валидации модели Course:
class Course < ApplicationRecord
validates :title, presence: true
end
В этом примере метод validates проверяет, что поле title присутствует. Если его нет, объект Course не будет сохранен в базу данных.
Виды валидаций
Разработчики Active Record добавили множество валидаций, которые закрывают большинство наших потребностей. Рассмотрим самые популярные из них.
Presence
Валидатор presence проверяет, что поле не пусто или не состоит только из пробелов. Пример валидатора:
class Course < ApplicationRecord
validates :title, presence: true
end
В этом примере валидация не пройдет, если мы попробуем сохранить курс без названия.
Length
Валидатор length используется для проверки длины строки. С его помощью мы можем проверить минимальную и максимальную длину, а также точную длину строки.
Пример валидатора:
class Course < ApplicationRecord
validates :description, length: { minimum: 128, maximum: 512 }
end
В этом примере описание курса должно быть длиной от 128 до 512 символов.
Numericality
Валидатор numericality проверяет, что значение поля является числом. Мы можем указать условие, при котором значение должно быть только целым числом. Также этот валидатор может проверить значение на больше или меньше.
Пример валидатора:
class Course < ApplicationRecord
validates :price, numericality: { greater_than_or_equal_to: 0 }
end
В этом примере валидация проверяет, что цена — это число, которое больше или равно нулю.
Uniqueness
Валидатор uniqueness проверяет, что значение поля уникально в базе данных. В следующем примере мы рассмотрим валидацию поля email модели Student, которая описывает данные учеников Hexlet:
class Student < ApplicationRecord
validates :email, uniqueness: true
end
Пример показывает валидацию, при которой каждый объект модели Student должен иметь уникальный адрес электронной почты.
Format
Валидатор format используется для проверки формата значения поля. Мы можем задать формат с помощью регулярного выражения. Например:
class Student < ApplicationRecord
validates :email, format: { with: URI::MailTo::EMAIL_REGEXP }
end
В этом примере мы проверяем, что введенный адрес электронной почты соответствует стандартному формату.
Inclusion
Валидатор inclusion проверяет, что значение поля включено в заданный список:
class Article < ApplicationRecord
validates :size, inclusion: { in: %w(small medium large),
message: "%{value} is not a valid size" }
end
В этом примере размер статьи курса должен быть одним из small, medium или large. Если это не так, валидация не пройдет, и будет выдано сообщение об ошибке.
Exclusion
Валидатор exclusion делает прямо противоположное inclusion валидатору. Он проверяет, что значение поля не включено в заданный список:
class Student < ApplicationRecord
validates :phone_prefix, exclusion: { in: %w(+1 +3 +6 +10),
message: "%{value} is incorrect" }
end
Если студент попытается указать один из некорректных префиксов номера телефона (+1, +3, +6 или +10), валидация не пройдет.
Сложные валидации
В некоторых случаях нам могут потребоваться более сложные валидации, которые нельзя реализовать с помощью встроенных валидаторов. В таком случае, мы можем определить свои валидации. Например:
class Course < ApplicationRecord
# Используется ключевое слово validate вместо стандартного validates
validate :discount_cannot_be_greater_than_price
# Метод, который выполняется при вызове одноименной валидации
def discount_cannot_be_greater_than_price
if discount > price
errors.add(:discount, "can't be greater than price")
end
end
end
Если скидка больше стоимости курса, то валидация не пройдет.
Валидация объекта
Выше мы говорили, что валидация вызывается при сохранении объекта. Но если мы хотим проверить валидность объекта модели Active Record, то мы можем самостоятельно вызвать у этого объекта метод valid? и invalid? соответственно.
Метод valid? возвращает true, если валидация объекта прошла успешно, и false, если провалилась.
У нас есть модель Course с валидацией наличия поля title:
class Course < ApplicationRecord
validates :title, presence: true
end
Теперь, когда мы создаем объект модели Course, мы можем использовать метод valid?, чтобы проверить, удовлетворяет ли он валидации:
course = Course.new(title: '')
puts course.valid? # Это выведет 'false', потому что title пуст
course.title = 'Основы Ruby on rails'
puts course.valid? # Это выведет 'true', потому что title содержит название
Если валидация не прошла, мы можем получить доступ к ошибкам через метод errors:
course = Course.new(title: '')
course.valid?
# Puts выведет ["can't be blank"], что является ошибкой валидации
puts course.errors[:title]
Вывод
Валидации — это важный аспект при разработке Ruby on rails проекта. Они помогают обеспечить точность и надежность данных для сохранения в базе. Rails предоставляет множество встроенных валидаций:
- Presence — проверяет, что поле не пусто.
- Length — проверяет длину значения поля.
- Numericality — проверяет, что значение поля является числом.
- Uniqueness — проверяет, что значение поля уникально в базе данных.
- Format — проверяет, что значение поля соответствует заданному формату.
- Inclusion — проверяет, что значение поля включено в заданный список.
- Exclusion — проверяет, что значение поля не включено в заданный список.
Но если и этого недостаточно, то мы можем создать собственный сценарий валидации с помощью ключевого слова validate. А с помощью метода valid? можем проверить валидность объекта без его сохранения.
Самостоятельная работа
- Повторите шаги из теории.
- Добавьте валидацию к созданным ранее моделям
Дополнительные материалы
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.