Rails:有关迁移的问题

时间:2012-03-26 15:48:43

标签: ruby-on-rails ruby devise migration rake

我是Ruby on Rails的新手,我知道事情,但现在我必须面对真实的项目和的事情。我写了这个迁移:

  def change
    change_table :societies do |t|
      ## Database authenticatable
        t.string :email,              :null => false, :default => ""
        t.string :encrypted_password, :null => false, :default => ""

        ## Recoverable
        t.string   :reset_password_token
        t.datetime :reset_password_sent_at

        ## Rememberable
        t.datetime :remember_created_at

        ## Trackable
        t.integer  :sign_in_count, :default => 0
        t.datetime :current_sign_in_at
        t.datetime :last_sign_in_at
        t.string   :current_sign_in_ip
        t.string   :last_sign_in_ip

        # Token authenticatable
        t.string :authentication_token

当我尝试回滚时,我得到 ActiveRecord :: IrreversibleMigration 我知道错误在哪里,我的问题是:

我是否可以更改已应用的迁移以修复错误,然后重新运行rake db:migrate?
我是否必须使用up / down方法修改迁移,还原迁移然后再次迁移?
或者我可能会通过新的迁移删除表并重新创建它?哪种是最佳做法?

3 个答案:

答案 0 :(得分:4)

<强> TL; DR

  • 如果更改尚未投入生产,您通常可以轻松修改迁移。
  • 最佳做法是使迁移文件尽可能保持干净且数量和范围有限。
  • 如果更改已经在生产中,或者如果您修改了其他开发人员会使其生活困难,那么请添加其他迁移以修复错误的先前迁移。
  • 如果您只是添加功能(能够撤消迁移),而不是更改迁移最初的功能,那么您可以稍微宽松一下这些指南。

完整答案:

如果您尚未将任何内容推送到远程/中央存储库,则可以根据新的更改执行任何操作,因为它只会影响您。只需更改数据库和迁移文件即可满足您的需求。实际上,在这里更改迁移文件是最佳实践,而不是通过不必要的迁移来混乱源代码库。

如果你已经推送到远程但你知道某些还没有其他人从该分支中​​撤出(例如,你是该分支的唯一用户,或者它是一个小团队并且您已与所有成员进行了沟通),您可以再次使用最近的更改(包括迁移)执行任何操作。

现在,如果其他人已经撤离,但改变尚未生效,如果团队规模不是太大,您通常仍可以随心所欲地做任何事情。请注意,如果他们不知道您正在做什么,那么更改已经提交的迁移文件可能会导致另一个开发人员烦人的开发环境重新引导,因此请告诉他们他们需要做些什么才能获得他们的开发环境回到同步。因此,在这种情况下,请与团队的其他成员清楚地沟通。

最后,如果迁移已经进入生产和运行(或者如果开发团队太大而无法有效协调与其他开发人员的迁移),该怎么办?在这种情况下,通常最好编写一个新的迁移来反转错误的迁移。在极少数情况下,一个优秀的牛仔程序员可以通过手动编辑生产中已经运行的迁移(以及甚至可能是个好主意的地方)来逃避,但在这种情况下你必须非常小心,因为你正在玩火(如果搞砸了,还有一个简单的恢复机制。)

在任何情况下,如果您进行了彻底的测试,那么错误的迁移应该非常罕见地将其一直用于生产。对于错误的迁移来说,甚至将其迁移到中央存储库(在多个开发人员正在处理的任何分支中)都应该是不寻常的。

有了这个,让我们说按照上面的指导方针你已经决定改变你的迁移是可以的。然后,回答您的具体问题:

  

我是否可以更改已应用的迁移以修复错误   重新运行rake db:migrate?

不,运行迁移后,其ID将存储在数据库中,即使文件发生更改,也不会再次运行。

  

或者我是否必须使用up / down方法修改迁移,还原迁移然后再次迁移?

您应该使用up / down方法修改迁移,是的。但正如您已经说过的那样,您无法以官方方式恢复迁移。相反,您可以从空的平板重新引导环境,也可以使用SQL查询手动恢复迁移(请记住还要从迁移表中删除关联的ID)。然后,重新运行迁移。

  

或许我可以通过新的迁移删除表并重新创建它?

除非你被迫(不过要小心,在生产中运行它时你不要在这个过程中无意中杀死数据!),不要这样做。)

最后,应该注意的是,如果您对迁移文件进行的唯一更改是将“更改”拆分为“上/下”方法,并且修改后“up”部分完全相同,你甚至可以避免偏离上述指导原则,因为它不会伤害其他开发人员(他们现在可以回滚以前无法回滚的东西)。但在这种情况下谨慎一点 - 你不想搞砸,偶然也不小心改变up方法。

答案 1 :(得分:1)

根据Rails Migrations Guide

  

通常编辑现有的迁移不是一个好主意:你会   为自己和同事创造额外的工作并造成专业   如果现有版本的迁移已经存在,那就令人头疼   在生产机器上运行。相反,您应该编写新的迁移   执行您需要的更改。编辑新生成的   尚未提交源控制的迁移(或更多   一般来说,这已经超出了你的发展范围   机器)相对无害

答案 2 :(得分:1)

您无法在更改表中使用更改。所以你需要一个上下方法。请查看http://guides.rubyonrails.org/migrations.html以获取更多详细信息,但无法轻松撤消change_table,因此rails无法自动为您执行此操作。它需要有关如何正确执行的更多详细信息。

您可以使用的内容列表从上页更改:

  • add_column
  • add_index
  • add_timestamps
  • CREATE_TABLE
  • remove_timestamps
  • rename_column
  • rename_index
  • rename_table

对于您的上一个问题,我建议添加另一个迁移,如果已经对生产数据库执行了更改,或者以简单的方式执行此操作,则会撤消更改。如果不是,您可以只编辑迁移并手动修复问题,但这样做更有效。