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

Миграции призваны заменить всякие графические 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. я вот подумал, а есть ли в рунете актуальные руководства по использованию миграций? Или, может, стоит таковое написать?

Комментарии

  • Igor Zubkov 8 августа 2009

    > Всяческие тестовые или демонстрационные данные лучше
    > заводить не миграцией, а rake-задачей или фикстурами,
    > чтоб не засорять базу.

    А пример того как это нужно использовать правильно можно?

  • a_djo 10 августа 2009

    Я еще использую create! с воскл. знаком для выкидывания экзепшинов в миграциях. (User.create!)

  • mikhailov 20 августа 2009

    Нормально написал, но несколько замечаний
    1) нельзя писать миграции, так чтобы при db:migrate у тебя будет полноценная готовая база. для этого надо использовать что то типа rake db:bootstrap – набор рейктасков, которые вносят в базу первоначальные данные, либо тупо rake db:fixtures:load в рабочую базу – иногда(редко случается) ничего лучше не придумаешь.
    Миграции – призваны, верно заметил, актаулизировать версию базы данных проекта в какой то определенный момент времени.
    Забыл сказать про необратимые миграции – raise ActiveRecord::IrreversibleMigration, «Can’t recover the deleted tags»

    2) если не уверен. что модель проинициализирована – сделай это в миграциях, т.к. миграции наследуются от ActiveRecord

    3) иногда для выполнение какой то задачи (создание отчета, например), требуется наличие индекса, но этот индекс неуместен после создания отчета – просто сделать так: в миграции перед sql запросом добавить индекс, а после – удалить.

    4) rake -T посмотри, какие возмжности дают рельсовые таски

    • Леонид Шевцов 20 августа 2009

      Спасибо за необратимые миграции, пригодится.
      Фикстуры неудобно использовать, если нужно наполнить несколько связанных моделей, так что сейчас пришли к использованию db/seeds.rb, куда в rails 3 будут заноситься действия по наполнению базы.

Оставить комментарий

  • (или OpenID)
  •