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 — важный инструмент для эффективной и безопасной разработки.

Рекомендуемые программы

+7 800 100 22 47

бесплатно по РФ

+7 495 085 21 62

бесплатно по Москве

108813 г. Москва, вн.тер.г. поселение Московский,
г. Московский, ул. Солнечная, д. 3А, стр. 1, помещ. 20Б/3
ОГРН 1217300010476
ИНН 7325174845