【问题标题】:How should I *intentionally* stop a migration?我应该如何*故意*停止迁移?
【发布时间】:2014-11-26 20:10:45
【问题描述】:

我有一个要运行的迁移,但在它运行之前我想验证某些条件(即迁移调用模型上的实例方法,并且我想确保该方法在运行迁移之前存在)。

考虑到这一点,我找不到任何说明在验证未通过时如何停止迁移的文档。似乎最有可能引发异常是执行此操作的明智方法。我发现ActiveRecord::Rollback 看起来不错,因为它显式回滚事务,但它也具有事务回滚后不重新引发的特性,因此我可能不会看到我附加的任何消息例外。

我一直在搜索“rails 取消迁移”之类的内容,但所有结果似乎都涉及无意中取消的迁移。我想在某些情况下故意(并且优雅地)失败。

【问题讨论】:

  • 有趣的问题。 FWIW我也想过手动引发异常。不能对它是否是最好的方法做出任何声明,但它肯定会奏效。副作用当然是迁移不会被认为是成功的,下次你rake db:migrate时会尝试再次运行(我相信这是你的意图)。

标签: ruby-on-rails rails-activerecord rails-migrations


【解决方案1】:

我最终做的实际上是raise Exception,因为ActiveRecord::Rollback 会将迁移计为已完成,并且在修复错误后不允许重新运行它。

【讨论】:

    【解决方案2】:

    如果您在迁移中引发异常,它将停止迁移。

    根据您的需要,您还可以尝试创建交互式迁移:

    puts "*** What would you like to do? ***"
    puts "(a)dd columns AND copy data"
    puts "(c)olumns only (no data copying)"
    puts "(d)ata only (no column adding)"
    puts "(q)uit"
    reply = $stdin.gets.chomp
    

    或者只是将if 置信于您的迁移中,并且仅根据状态运行命令。迁移仍将完成,但操作不会运行。

    【讨论】:

    • 如果交互仅在条件失败时触发(“它坏了。你想做什么?”),则交互将起作用。在生产中运行(即在远程主机上)可能也很困难。如果操作未运行,我想避免完成迁移,因为我想在解决问题后返回并重新运行。 (不过,如果我不想重新运行,那将是有效的。)
    猜你喜欢
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-17
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多