Зарегистрируйтесь, чтобы продолжить обучение

Основные концепции Ruby: ActiveRecord (ORM)

В этом уроке мы разберем общие концепции, присущие ORM. Каждая из этих концепций рассматривается дальше в курсе.

ORM — это общее название для фреймворков, которые позволяют автоматически связать базу данных с кодом. Они стараются скрыть существование базы данных, насколько это возможно. Взамен программисту дают возможность оперировать данными в базе через специальный интерфейс.

Вместо построения SQL-запросов программист вызывает простые методы, а остальную работу берет на себя ORM. Например, c помощью ORM языка Ruby мы можем создать объект класса и сохранить его в базу данных:

course = Course.new
course.title = 'Ruby'
course.save # сохранение курса в базу

ORM бывают разными. Active Record относится к наиболее распространенному и простому типу ORM. Он реализует одноименный шаблон проектирования Active Record.

Этот шаблон базируется на идее, что каждой таблице в приложении соответствует один класс. Этот класс отвечает за реализацию бизнес логики и взаимодействие с базой данных. Последнее обычно появляется в модели за счет наследования от базового класса ORM.

Модель

Ниже представлен код определения класса модели Course. Даже без явного определения методов внутри, класс модели обладает всей функциональностью для работы с записями курсов в базе данных:

class Course < ApplicationRecord
end

Каждый объект данного класса соответствует одной записи из этой таблицы. За преобразования данных в объекты и обратно, отвечает ORM. Программисту лишь нужно использовать правильные методы, чтобы извлечь объекты и их модификации. Примеры таких методов:

# Поиск курса по идентификатору
course = Course.find(1)

# Обновление курса
course.title = 'Ruby on Rails'
# Сохранение в базу
course.save

# Удаление записи в базе данных
course.destroy

# Общее число курсов
# SELECT COUNT(*) FROM courses;
Course.count

Выборки

Важная часть любой ORM — это Query Interface или интерфейс запросов. Это абстракция поверх SQL, которая упрощает генерацию запросов. Она обычно выглядит как цепочка функций, каждая из которых отвечает за конкретную часть SQL, например: ORDER, SELECT или WHERE. Например, в следующей строчке кода мы получаем все активные курсы и сортируем их по названию:

courses = Course.where(state: 'active').order(title: :desc)

В тех случаях, когда этого языка недостаточно или запрос слишком сложный, ORM позволяет использовать SQL-вставки:

courses = Course.where("title LIKE '%Ruby%' AND state = 'active'")

Схема

Еще одна обязанность ORM — изменение схемы базы данных: добавление, удаление и модификация таблиц. Делается это, как правило, не на чистом SQL, а с помощью специального языка. Это позволяет работать с ORM и не отвлекаться на особенности конкретных баз данных.

ORM сама создает правильный SQL-запрос, который подходит под конкретную базу данных. Вот так выглядит код схемы с созданием таблицы courses:

ActiveRecord::Schema.define(version: 2023_05_04_123456) do

  create_table "courses", force: :cascade do |t|
    t.string "title", null: false
    t.text "description"
    t.decimal "price", default: 0
    t.timestamps
  end

end

В Active Record используется подход Database First. Чтобы создать новые модели или изменить поведение старых, нужно сначала изменить базу данных, а ORM сама подхватывает изменения и работает с ними.

Например, чтобы добавить новое свойство, достаточно добавить новую колонку. В коде ничего менять не нужно, ORM автоматически начинает работать.

В некоторых ORM встречается подход Code First. В таком случае изменения делаются не в базе, а в коде. А дальше ORM сама формирует необходимые изменения для базы данных, подстраивая ее под код.

Миграции

Любая база данных в процессе жизни приложения изменяется. В нее добавляются новые таблицы, удаляются и меняются старые. Этот процесс бесконечный.

Изменения в базе данных выполняются с помощью механизма миграций. Миграция — это обычно файл, который содержит SQL, меняющий текущую схему базы данных. Далее приведен пример кода файла миграции для создания таблицы курса:

class CreateCourses < ActiveRecord::Migration[6.1]
  def change
    create_table :courses do |t|
      t.string :title, null: false
      t.text :description
      t.decimal :price, default: 0
      t.timestamps
    end
  end
end

Когда этот файл создан, то происходит процесс, который называют «применением миграций». Он выполняется с помощью утилиты командной строки. В Ruby on Rails это выглядит так:

rake db:migrate

В процессе выполнения этой команды автоматически проверяются, какие миграции были уже применены, а какие — нет. Применяются только те миграции, которые еще не выполнены на текущей базе данных.

Выводы

ORM помогает программистам легче и быстрее работать с базами данных, превращая их таблицы в классы и строки в объекты. Это делает код проще для понимания и управления. ORM — важный инструмент для эффективной и безопасной разработки.


Самостоятельная работа

Зайдите в репозиторий hexlet CV и найдите схему БД проекта. Посмотрите, какие таблицы существуют в проекте


Дополнительные материалы

  1. Основы ActiveRecord

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff