Как отменить неудачную миграцию рельсов? Я ожидал, что rake db:rollback
это отменит неудачную миграцию, но нет, это откатит предыдущую миграцию (неудачная миграция минус один). И rake db:migrate:down VERSION=myfailedmigration
тоже не работает. Я сталкивался с этим несколько раз, и это очень расстраивает. Вот простой тест, который я провел, чтобы воспроизвести проблему:
class SimpleTest < ActiveRecord::Migration
def self.up
add_column :assets, :test, :integer
# the following syntax error will cause the migration to fail
add_column :asset, :test2, :integer
end
def self.down
remove_column :assets, :test
remove_column :assets, :test2
end
end
результат:
== SimpleTest: перенос ============================================= ======== - add_column (: assets,: test,: integer) -> 0,0932 с - add_column (: актив,: ошибка) грабли прерваны! Произошла ошибка, все последующие миграции отменены: неправильное количество аргументов (2 вместо 3)
ок, давай откатим назад:
$ rake db: откат == AddLevelsToRoles: возврат =============================================== == - remove_column (: роли,: уровень) -> 0,0778 с == AddLevelsToRoles: возвращено (0,0779 с) ======================================
а? это была моя последняя миграция перед SimpleTest, а не неудачная миграция. (И о, было бы неплохо, если бы вывод миграции содержал номер версии.)
Итак, давайте попробуем запустить простой тест для неудачной миграции:
$ rake db: migrate: down ВЕРСИЯ = 20090326173033 $
Ничего не происходит, и выхода тоже нет. Но, может быть, он все равно выполнил миграцию? Итак, давайте исправим синтаксическую ошибку в миграции SimpleTest и попробуем запустить ее снова.
$ rake db: migrate: up VERSION = 20090326173033 == SimpleTest: перенос ============================================= ======== - add_column (: assets,: test,: integer) грабли прерваны! Mysql :: Ошибка: повторяющееся имя столбца 'test': ALTER TABLE `assets` ADD` test` int (11)
Нет. Очевидно, что migrate: down не сработал. Это не сбой, это просто не выполняется.
Нет другого способа избавиться от этой повторяющейся таблицы, кроме как вручную войти в базу данных и удалить ее, а затем запустить тест. Должен быть способ получше.