CRUD — это акроним, включающий в себя четыре операции, которые можно осуществлять с данными:
- Create — создание
- Read — чтение
- Update — обновление
- Delete — удаление
Данные операции являются фундаментом для любой системы управления базами данных.
Операции CRUD легко реализуются и интегрируются в приложение с помощью Ruby on Rails и его встроенного интерфейса Active Record. Active Record предоставляет высокоуровневый интерфейс для взаимодействия с данными. Это позволяет разработчикам сосредоточиться на бизнес-логике и не беспокоиться о деталях управления базой данных.
В этом уроке мы разберем, как в Ruby on Rails реализуются операции CRUD с использованием Active Record.
Создание
Рассмотрим, как создать новую запись в базе данных с помощью Active Record.
Модель Student
имеет атрибуты first_name
и last_name
. Далее создадим нового студента:
# создаем новый объект модели Student
student = Student.new
# присваиваем атрибутам first_name и last_name объекта student значения
student.first_name = 'Hexlet'
student.last_name = 'Student'
# сохраняем объект student
student.save
Другой способ создать запись — использовать метод create
:
student = Student.create(first_name: 'Hexlet', last_name: 'Student')
Метод create
объединяет шаги new
и save
, создает новый объект и сохраняет его в базе данных.
Active Record также предлагает метод create!
. Он отличается от create
тем, что вызывает исключение ActiveRecord::RecordInvalid
при невозможности сохранить объект.
Далее представлен пример использования:
begin
student = Student.create!(first_name: 'Hexlet', last_name: 'Student')
rescue ActiveRecord::RecordInvalid => invalid
puts invalid.record.errors
end
В этом примере мы пробуем создать и сохранить нового студента с помощью create!
. Если из-за ошибок валидации студент не может быть сохранен, мы перехватываем исключение ActiveRecord::RecordInvalid
и выводим ошибки.
Использование create!
вместо create
помогает лучше управлять ошибками и предоставляет четкое понимание того, что происходит в случае неудачного сохранения записи.
Чтение
Теперь, когда у нас есть записи в базе данных, мы можем извлекать их с помощью различных методов чтения Active Record.
Для получения всех записей из таблицы мы используем метод all
:
students = Student.all
Чтобы найти конкретную запись по ее id, мы используем метод find
:
student = Student.find(1) # находит студента с id 1
Если нам нужно выбрать только определенные записи, мы можем использовать where
. Например:
students = Student.where(first_name: 'Hexlet') # находит всех студентов с именем Hexlet
Если нам нужно найти определенную запись по атрибутам, то нам поможет метод find_by
. Например:
student = Student.find_by(first_name: 'Hexlet', last_name: 'Student')
В этом примере find_by
возвращает первый объект Student
, который соответствует условиям, или nil, если такого объекта не найдено.
find_by
всегда возвращает только одну запись, даже если в базе данных есть несколько записей по данному запросу.
Метод find_by
отличается от find
не только поиском по любым полям объекта. Если записи не существует, find
выбросит исключение, а find_by
вернет nil.
Обновление
Сначала нам нужно найти объект, изменить его атрибуты, а затем сохранить эти изменения для обновления записи в базе:
student = Student.find(1)
student.first_name = 'Hexleta'
student.save
В примере выше мы находим студента с id 1. Далее изменяем его имя на Hexleta
и сохраняем эти изменения.
Если нам нужно обновить несколько записей одновременно, мы можем использовать update_all
. Например, чтобы изменить имя всех студентов с именем Hexlet
на Hexleta
:
Student.where(first_name: 'Hexlet').update_all(first_name: 'Hexleta')
Но есть одно замечание. Метод update_all
напрямую отправляет запрос в базу данных в обход валидаций модели. Поэтому его нужно использовать крайне осторожно.
Удаление
Мы можем использовать методы destroy
, destroy_all
, delete
и delete_all
для удаления записей из базы данных.
Метод destroy
удаляет запись и вызывает все действия, которые связанны с удалением. Например, удаление связанных объектов:
Допустим, у нас есть модель Course
, которая имеет множество Student
:
class Course < ActiveRecord::Base
# параметр dependent: :destroy указывает на связанное уничтожение
has_many :students, dependent: :destroy
end
Теперь, когда мы удаляем Course
, связанные объекты Student
также будут уничтожены:
course = Course.find(1)
course.destroy
Аналогичным образом работает метод destroy_all
, только для всех записей, которые мы выбрали:
courses = Course.where(first_name: 'Hexlet')
courses.destroy_all
Метод delete
в отличие от destroy
удаляет запись напрямую из базы данных. Это может быть полезно, когда нам нужно быстро удалить запись без дополнительной обработки. В этом случае нужно быть осторожным, так как это может привести к нарушению целостности данных.
В следующем примере связанные записи Student
с объектом course
останутся в таблице даже после его удаления:
course = Course.find(1)
course.delete
delete_all
удаляет все записи аналогично методу delete
, которые мы нашли:
courses = Course.where(first_name: 'Hexlet')
courses.delete_all
Выводы
Active Record в Ruby on Rails упрощает работу с базой данных и трансформирует таблицы базы данных в объекты Ruby. С помощью Active Record мы можем легко создавать, читать, обновлять и удалять записи в нашей базе данных.
Самостоятельная работа
- Повторите шаги из теории.
- Создайте контроллеры и реализуйте CRUD для работы с созданными моделями.
- На страницу курса выведите название курса, название уроков, которые привязаны к этому курсу.
Дополнительные материалы
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.