44 подписчика
Чему можно научиться у миграций Rails
Я грозился начать рассказывать про фреймворки, пора это делать. Начнем с такой темы как миграции.
Миграции это механизм применения изменений к базе данных с помощью кода. Когда нам надо что-то поменять, мы создаем файлик с sql кодом, который затем применяется. Механизм миграций сам следит за тем что применилось и что нет. Это то, как они работают в простейшем случае.
В большинстве фреймворков (в микрофреймворках это не так) этот механизм встроенный, но иногда идет как отдельная часть, как в spring boot.
При более детальном взгляде, становится понятно, что миграции везде работают чуть по разному и один из самых продвинутых вариантов реализован в Rails. Ниже я приведу примеры того, как можно делать, чтобы вы могли под другим углом посмотреть на собственные фреймворки и решения. Возможно получится улучшить процесс. Начнем по порядку:
Генерация
Rails это db first фреймворк (как. и большинство), то есть модели работают базируясь на структуре базы данных, а не база данных меняется под структуру как в entity framework или django. Поэтому миграцию нужно генерировать самостоятельно, фреймворк этого не сделает.
Большая часть фреймворков может генерировать модель через cli, но далеко не все позволяют указывать набор полей который нужно сгенерировать:
bin/rails generate model Product name:string description:text category:references
Поддерживаются даже связи, который автоматически заполняются и в миграции и внутри модели. Все это можно легко поправить после того как оно будет сгенерировано.
Автооткат
Сама миграция не содержит привычных up и down. Внутри нее только один метод change. Rails умеет автоматически откатывать почти все, но работает это если мы используем его dsl для описания миграции, чистый sql не подойдет
class CreateProducts < ActiveRecord::Migration[7.1]
def change
create_table :products do |t|
t.string :name
t.text :description
t.timestamps
end
end
end
Если нужно всегда можно реализовать up и down отдельно
Схема
Вещь, которую после Rails внедрили многие фреймворки, например, Laravel (но сделано это довольно хреново). После того как накатывается миграция, rails автоматически обновляет файлик со схемой schema.rb. Этот файлик позволяет легко увидеть а чо там в базе без необходимости туда лезть. Он автоматически используется при накатывании проекта с нуля или в старте тестов. Работает это так: сначала грузим схему, затем миграции, которые добавились, но еще не применялись в текущем окружении. Наличие такой схемы позволяет легко удалять миграции, которые уже были накачены в продакшене.
Недавно я работал с Laravel и там сделали так, что схему нужно генерить ручками, что очень неудобно, плюс постоянно возникали проблемы с накаткой с нуля. Не знаю почему так у них получилось, в рельсе у меня подобных проблем не было.
Еще больше ништяков можно прочитать в офигенном гайде: https://guides.rubyonrails.org/active_record_migrations.html
Удаление
Помимо генераторов в рельсе реализован механизм удаления сущностей, например если я сделаю bin/rails destroy model Product, то она удалит все связанные сущности включая миграции. Это очень удобно когда идет активное добавление новых сущностей и возникают ошибки в именовании. Использовать этот механизм для моделей можно только если это локальные изменения.
Накат/Откат
Кроме простого накатить и откатить, в rails есть возможность указывать количество шагов отката и даже команда redo, которая перенакатывает нужное количество миграций (мне этого капец как не хватает в других местах).
bin/rails db:rollback STEP=3
bin/rails db:migrate:redo STEP=3
p.s. Поделитесь крутыми фишками миграций в ваших фреймворках
3 минуты
24 июля 2024