Rails迁移的详细指南

63 阅读4分钟

有时,由于代码的变化、错别字的修正、性能的提高、重定位等原因,需要在一个特性库中来回重新运行一次新的迁移。这可以通过使用最流行的rake命令来完成:rake db:rollback ,需要多少种类型就改多少种类型(或者更简单的rake db:rollback STEP=3 ,其中3是后退的步数),改变这个迁移,然后运行rake db:migrate ,就这样,很简单。不是吗?但是,如果这个迁移中又有一个错字或错误怎么办?你会怎么做?再次重复这个过程?这个问题可能会变得太烦人了。在这篇文章中,我向你展示了一个替代性的想法,如何减轻痛苦,并开始在编写迁移时感到更舒服。

问题

请想象一下下面的情况。在你的Rails应用程序中,有一个迁移的列表:

< > 20180317144803_migration1.rb
< > 20180317144804_migration2.rb
...
< > 20180317144814_migrationN.rb

这些迁移都已经在本地运行了。迁移的1 应该被改变。此外,很明显,没有必要重新运行所有的迁移,从2N 。把它们全部迁移回第一次迁移可能会变成一种痛苦,特别是在一个大的团队中处理一个大的问题,而这个团队经常改变迁移列表。针对这种情况,Rails提供了一个特殊的rake任务列表。

解决方案

长话短说,使用这个命令来运行迁移(它,只有它!):

rake db:migrate:down VERSION=20180317144803

然后在迁移中做一个必要的修改。然后继续运行迁移:

rake db:migrate:up VERSION=20180317144803

以这些rake任务作为问题的解决方案,请注意迁移可以在Rails中以任何顺序运行。但有时,它们可能会相互依赖。这种情况经常发生在项目开发的初期。所以,为了安全起见,至少要像这样来回运行一次所有的迁移:

rake db:rollback STEP=12
rake db:migrate

12 是这里的 。N

为了启动

至于甜点,请看这个命令,它显示了一个Rails项目中所有迁移的状态:

rake db:migrate:status

这是我在一个测试项目中得到的输出:

database: test-dev

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20180322190630  Remove special name
   up     20180326210602  Add default for users
  down    20180405124704  Add email
   up     20180406205508  Remove email

所以,在这个特殊的例子中,当它被执行rake db:migrate:up VERSION=20180405124704 ,状态变成了这样的状态:

database: test-dev

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20180322190630  Remove special name
   up     20180326210602  Add default for users
   up     20180405124704  Add email
   up     20180406205508  Remove email

rake db:migrate:down VERSION=20180405124704 ,相应地变成了之前的状态。

下面的命令也是有用的:

rake db:migrate:down VERSION=20180405124704

它将两个动作(向上和向下)合二为一:首先它试图做down ,然后--up 。关于这些任务的更多信息可以Rails的源代码中找到。

结论

迁移调整可能是一个巨大的痛苦。但值得庆幸的是,Rails,这个过程是一个愉快的工作。对于这种工作,可能会提供很多建议。但我更想提醒你的是,不可能为你日常工作中的每一种情况都写一份说明。只要阅读你在迁移中遇到的错误并遵循常识就可以了。例如,当一个错误说没有这样的表x ,试图被删除时,那么也许你做错了什么,你的数据库中出现了混乱。所以,也许应该用新的数据重新启动数据库。或者你可以在这次迁移中注释这一行,等迁移完成后再把它解开(在某些情况下,当你在试验你正在进行的新迁移时,可以接受这种做法)。