Як відкотити невдалу міграцію рейок? Я би очікував, що 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 (: активи,: тест,: ціле число) -> 0,0932 с - add_column (: актив,: помилка) граблі перервано! Сталася помилка, усі пізніші міграції скасовано: неправильна кількість аргументів (2 на 3)
гаразд, давайте відкотимо назад:
$ rake db: відкат == AddLevelsToRoles: повернення ================================================= == - remove_column (: role,: level) -> 0,0778 с == AddLevelsToRoles: відновлено (0,0779 с) ========================================
так? це була моя остання міграція до SimpleTest, а не невдала міграція. (І о, було б непогано, якби вихідні дані міграції включали номер версії.)
Тож давайте спробуємо запустити вниз для невдалої міграції SimpleTest:
$ rake db: migrate: down VERSION = 20090326173033 $
Нічого не відбувається, і результатів теж немає. Але, можливо, це все-таки перенесло міграцію? Тож дозволяє виправити синтаксичну помилку в міграції SimpleTest і спробувати запустити її знову.
$ rake db: migrate: up VERSION = 20090326173033 == SimpleTest: міграція =============================================== ======== - add_column (: активи,: тест,: ціле число) граблі перервано! Mysql :: Помилка: Повторювана назва стовпця 'test': ALTER TABLE `assets` ADD` test` int (11)
Ні. Очевидно, міграція: вниз не спрацювала. Це не підводить, це просто не виконує.
Неможливо позбутися цієї дублікатної таблиці, крім як вручну зайти в базу даних та видалити її, а потім запустити тест. Має бути кращий спосіб, ніж це.