“回滚”多DDL迁移

时间:2017-01-26 15:50:03

标签: ruby-on-rails ruby migration undo

大编辑,我现在谈论抽象的“行动”,而不是我以前的具体行动;这只是一个例子。

方案

我有一个迁移:

class XyzMigration < ActiveRecord:Migration
  def change
    first_action :a do ...
    some_action :b do ...
    other_action :c do ...
  end
end

如果所有3个动作(无论它们是什么;创建表,索引,修改列等)都成功,那么一切都很好。

但是:如果操作b失败,则迁移将成功执行a然后停止。

问题

问题在于:现在a已经完成,无论它是什么,但迁移还没有完成。也就是说,当我重试迁移时(在手动修复导致b失败的问题之后),我遇到a已经完成的失败,我必须手动撤消{{ 1}}。

我期待什么

我希望告诉Rails,如果迁移的后一步失败,则撤消所有已完成的步骤是安全的。从技术上讲,Rails能够做到这一点,因为a)撤销机制存在(我们可以使用a撤消完整的迁移,并且b)Rails知道每一步是否可逆。因此,假设在失败之前的所有先前步骤都是可逆的,它知道撤销是安全的。

是否有选项,标志,机制来做到这一点?我不希望自己编写逻辑,既不事先检查是否需要执行操作,也不希望捕获异常。

1 个答案:

答案 0 :(得分:1)

在创建表格之前检查表格是否存在:

# In Rails 2, 3 & 4:
unless ActiveRecord::Base.connection.table_exists?('a')
  create_table :a do ...
end
unless ActiveRecord::Base.connection.table_exists?('b')
  create_table :b do ...
end
# ...



# In rails 5:
unless ActiveRecord::Base.connection.data_source_exists?('a')
  create_table :a do ...
end
unless ActiveRecord::Base.connection.data_source_exists?('b')
  create_table :b do ...
end
# ...