Ruby on Rails

Что можно делать с миграциями в Rails

Миграции призваны заменить всякие SQL-менеджеры. Нет, серьезно: при работе с рельсами не нужны SQL-менеджеры, я гарантирую это. Зато нужно освоиться с механизмом миграций. И еще с script/console.

Миграции призваны заменить всякие графические SQL-менеджеры. Нет, серьезно: при работе с Ruby on Rails не нужны SQL-менеджеры, я гарантирую это. Зато нужно освоиться с механизмом миграций. И еще со script/console.

Как всегда, я не собираюсь писать еще одно руководство по использованию миграций, а намечу основные преимущества и фишки оных.

  • Структура базы хранится вместе с кодом, в репозитарии, неотрывно.
  • Всегда можно воссоздать состояние базы, соответствующее определенной стадии разработки.
  • Нет проблем создания на локальной машине реальной, работающей базы.
  • Миграции независимы от типа базы данных. Особенно если не использовать в них голый SQL.

В миграциях можно делать все, что можно сделать через SQL:

  • add_column, remove_column, rename_column, change_column – добавлять, убирать, изменять колонки в базе;
  • update_all – инициализирует новую колонку нужным значением;
  • add_index, remove_index – добавлять и убирать индексы
  • delete_all удалит записи SQL-запросом, destroy_all удалит соответствующие объекты, используя модель (все команды _all принимают в себя такой же блок условий, как и find);
  • выполнять любые операции над моделью – остерегайся только использования конструкций типа all.each {}, по понятным, надеюсь, причинам (памяти они жрут много);
  • заносить необходимые приложению данные в новосозданные таблицы – прямо через модель делаешь Klass.new и вперед;
  • выполнять любые SQL-запросы – execute "random sql code" – только в крайнем случае, ну ты понял.

Советы

  • Пользуйся миграциями для всех изменений структуры базы. Это же так просто:
    script/generate migration my_migration
    # ... заполняем код миграции
    rake db:migrate
  • При добавлении в базу каких-либо данных убедись, что не затираешь существующие и не создаешь дубликаты. Где-то так:

    unless User.exists(:admin => true)
      #add administrator user
      User.create(:login => 'root', :password => 'root', :admin => true)
    end
  • Не изменяй содержимое миграции, если ее уже мог применить кто-то, кроме тебя. Приведение расходящихся миграций в порядок – страшное дело. Лучше создай рядом новую, благо, количество миграций ничем не ограничено.
  • Всегда, когда это возможно, реализуй обратную миграцию.
  • А еще у Rails-приложения есть такая штука, как схема базы. Находится она в db/schema.rb и содержит текущее состояние базы (опять-таки, это если не менять базу в обход миграций, но и в этом случае можно актуализировать схему командой rake db:schema:dump). Схему можно целиком и полностью запихать в одну миграцию. Это удобно, если ты собираешься распространять исходный код приложения – кучу маленьких неаккуратных миграций можно заменить одной. Только не забудь, что кроме структуры, приложению могут быть нужны исходные данные – их также нужно включить в эту самую миграцию.
  • Всяческие тестовые или демонстрационные данные лучше заводить не миграцией, а rake-задачей или фикстурами, чтоб не засорять базу.

Я так думаю: нужно писать такие миграции, чтобы, выполнив rake db:migrate на пустой базе, я бы оказался с работоспособной базой. И с работоспособным приложением. Удачи в этом, сделаем жизнь еще чуть проще!

P.S. я вот подумал, а есть ли в рунете актуальные руководства по использованию миграций? Или, может, стоит таковое написать?