Как вы откатываете неудачную миграцию рельсов? Я ожидал бы, что 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: migrating ===================================================== -- add_column(:assets, :test, :integer) -> 0.0932s -- add_column(:asset, :error) rake aborted! An error has occurred, all later migrations canceled: wrong number of arguments (2 for 3)
ok, верните его назад:
$ rake db:rollback == AddLevelsToRoles: reverting =============================================== -- remove_column(:roles, :level) -> 0.0778s == AddLevelsToRoles: reverted (0.0779s) ======================================
а? это была моя последняя миграция до SimpleTest, а не неудачная миграция. (И, о, было бы неплохо, если выход миграции включал номер версии.)
Итак, попробуйте запустить down для неудавшейся миграции SimpleTest:
$ rake db:migrate:down VERSION=20090326173033 $
Ничего не происходит, и нет вывода. Но, может быть, он все-таки прошел миграцию? Поэтому давайте исправить ошибку синтаксиса в миграции SimpleTest и попытаться запустить ее снова.
$ rake db:migrate:up VERSION=20090326173033 == SimpleTest: migrating ===================================================== -- add_column(:assets, :test, :integer) rake aborted! Mysql::Error: Duplicate column name 'test': ALTER TABLE `assets` ADD `test` int(11)
Неа. Очевидно, мигрировать: вниз не получилось. Это не терпит неудачу, оно просто не выполняется.
Невозможно избавиться от этой повторяющейся таблицы, кроме ручного входа в базу данных и ее удаления, а затем запустить тест. Там должен быть лучший способ.