rake db:rollback恢复错误的迁移

时间:2013-02-05 16:14:17

标签: ruby-on-rails-3.2 rake rails-migrations

我遇到了恢复上次迁移的问题。

自从我为评级安装'letrate'宝石以来,任何rake db:rollback都会精确地恢复 letrate gem 迁移,而不是预期的最后一次迁移。

我怀疑这是由于宝石本身。

任何想法如何解决这个问题,所以我可以享受非常方便的回滚?

同样的问题:

rake db:migrate:redo

结果:

==  CreateRates: reverting ====================================================
-- drop_table(:rates)
   -> 0.0224s
==  CreateRates: reverted (0.0225s) ===========================================

==  CreateRates: migrating ====================================================
-- create_table(:rates)
NOTICE:  CREATE TABLE will create implicit sequence "rates_id_seq" for serial column "rates.id"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "rates_pkey" for table "rates"
   -> 0.1787s
-- add_index(:rates, :rater_id)
   -> 0.0032s
-- add_index(:rates, [:rateable_id, :rateable_type])
   -> 0.0024s
==  CreateRates: migrated (0.1850s) ===========================================

rake db:migrate:status

...
   up     20121205224038  Rename user address column
   up     20121206125016587  ********** NO FILE **********
   up     20121206125016605  ********** NO FILE **********
   up     20121210152550  Create reservations
   up     20121210180233  Create transactions
   up     20121210215840  ********** NO FILE **********
   up     20121218144200  Create videos
   up     20121218144800  Add video to videos
   up     20130108225007  Devise invitable add to users
   up     20130130202046  Acts as taggable on migration
   up     20130205154206  Create commissions
   up     20130207133520  Add user id to event transition

和文件

-rw-r--r--@  1 joel  staff   137 Dec  7 16:40 20121205224038_rename_user_address_column.rb
-rw-r--r--@  1 joel  staff   443 Dec  7 16:40 20121206125016587_create_rating_caches.rb
-rw-r--r--@  1 joel  staff   432 Dec  7 16:40 20121206125016605_create_rates.rb
-rw-r--r--@  1 joel  staff   429 Dec 10 23:30 20121210152550_create_reservations.rb
-rw-r--r--@  1 joel  staff   414 Dec 10 19:03 20121210180233_create_transactions.rb
-rw-r--r--@  1 joel  staff   237 Dec 18 15:44 20121218144200_create_videos.rb
-rw-r--r--@  1 joel  staff   172 Dec 18 16:18 20121218144800_add_video_to_videos.rb
-rw-r--r--@  1 joel  staff   758 Jan  8 23:50 20130108225007_devise_invitable_add_to_users.rb
-rw-r--r--   1 joel  admin   775 Jan 30 21:20 20130130202046_acts_as_taggable_on_migration.rb
-rw-r--r--@  1 joel  admin   422 Feb  5 17:05 20130205154206_create_commissions.rb
-rw-r--r--@  1 joel  admin   266 Feb  7 15:20 20130207133520_add_user_id_to_event_transition.rb

1 个答案:

答案 0 :(得分:5)

好的,问题是您的letrate迁移的版本号。 Rails只是命令迁移文件中的时间戳,以了解最近应用的时间戳。时间戳中还有3位数字, 20121206125016605_create_rates.rb 20121206125016587_create_rating_caches 始终会被检测为最后一次迁移。

让我们尝试修复它并清理您的迁移状态。首先回滚有问题的迁移:

rake db:rollback STEP=2

您的rake db:migrate:status现在应该如下所示:

up     20121205224038  Rename user address column
up     20121210152550  Create reservations
up     20121210180233  Create transactions
up     20121210215840  ********** NO FILE **********
up     20121218144200  Create videos
up     20121218144800  Add video to videos
up     20130108225007  Devise invitable add to users
up     20130130202046  Acts as taggable on migration
up     20130205154206  Create commissions
up     20130207133520  Add user id to event transition

现在让我们修复他们的版本号(假设您的迁移位于默认的db/migrate文件夹中)

mv db/migrate/20121206125016605_create_rates.rb db/migrate/20121206125017_create_rates.rb
mv db/migrate/20121206125016587_create_rating_caches.rb db/migrate/20121206125016_create_rating_caches.rb

现在您的db:migrate:status应如下所示:

up     20121205224038  Rename user address column
down   20121206125016  Create rating caches
down   20121206125016  Create rates  
up     20121210152550  Create reservations
up     20121210180233  Create transactions
up     20121210215840  ********** NO FILE **********
up     20121218144200  Create videos
up     20121218144800  Add video to videos
up     20130108225007  Devise invitable add to users
up     20130130202046  Acts as taggable on migration
up     20130205154206  Create commissions
up     20130207133520  Add user id to event transition

现在“时间轴”已修复,但我们仍需要重新应用这些迁移。 rake db:migrate无效,因为上一次迁移现在是 20130207133520_add_user_id_to_event_transition.rb 而且已经应用​​了所以rake认为它是最新的...所以我们必须欺骗rake:编辑每一个通过注释down方法中的所有内容,在迁移状态输出中显示在 20121206125017_create_rates.rb 之后的迁移文件。如果只有change方法,请对其进行注释并创建空的向上和向下方法。因此所有这些下行方法都是这样的:

def down
  # This is the old code
  # which I will uncomment later...
end

您还需要创建一个空迁移,因为存在一个没有文件关联的奇怪迁移(********** NO FILE **********一个)。因此,使用以下内容创建名为 db / migrate / 20121210215840_ghost_migration.rb 的文件:

class GhostMigration < ActiveRecord::Migration
  def up
  end

  def down
  end
end

现在我们已经准备好一直模拟滚动。

rake db:rollback STEP=9

现在,迁移状态输出应为

up     20121205224038  Rename user address column
down   20121206125016  Create rating caches
down   20121206125016  Create ratings
down   20121210152550  Create reservations
down   20121210180233  Create transactions
down   20121210215840  Ghost migration
down   20121218144200  Create videos
down   20121218144800  Add video to videos
down   20130108225007  Devise invitable add to users
down   20130130202046  Acts as taggable on migration
down   20130205154206  Create commissions
down   20130207133520  Add user id to event transition

现在,您可以通过取消注释之前评论的内容并删除“Ghost migration”文件来将文件更改回原始状态。您应该以与我们相同的方式对“up”方法进行评论。使用之前的down方法,删除“Ghost migration”文件并迁移所有内容

rake db:migrate

最后取消注释你在文件中注释掉的所有内容,之后应该顺利运行(我希望)。

关于为什么会发生这种情况,我认为这实际上是由于gem本身,我认为不应该生成具有无效(或至少非标准)版本号的迁移。看起来gem在同一秒内生成了两次迁移,因此作者可能会添加这3个额外的数字以防止版本号冲突。我认为在同一次迁移中做所有事情会更好。

我希望这可以帮助您解决问题!

更新

也许我过于复杂。如果您不介意实际回滚所有迁移然后再次迁移它们,则不需要对任何文件进行任何注释(尽管仍然需要“Ghost迁移”技巧)。我觉得这样会更安全。