如何在rails中创建可逆迁移帮助程序?

时间:2013-06-07 11:37:11

标签: ruby-on-rails ruby migration

我发现自己必须在rails应用程序的几个表上执行非常相似的sql语句(除了表名之外可能有1个参数)。结果,我得到了很多类似的迁移,比如这个:

class DoSomeSQLOnUser < ActiveRecord::Migration
  def up
    execute('some long sql that alters the user.field1')
    execute('some long sql that alters the user.field2')
  end

  def down
    execute('some sql that undoes the changes')
  end
end

然后我对客户,销售等有同样的想法。

我想扩展ActiveRecord::Migration以便我可以这样做:

class DoSomeSQLOnUser < ActiveRecord::Migration
  def change
    do_custom_thing_on :users, :field1
    do_custom_thing_on :users, :field2
  end
end

我该怎么做?我认为我知道如何将操作分为上下,如下所示:

class DoSomeSQLOnUser < ActiveRecord::Migration
  def up
    do_custom_thing_on :users, :field1
    do_custom_thing_on :users, :field2
  end
  def down
    undo_custom_thing_on :users, :field1
    undo_custom_thing_on :users, :field2
  end
end

但这样做是为了让变化“可逆”逃脱了我。

4 个答案:

答案 0 :(得分:2)

这似乎不是官方支持的方式,因此您可能需要打开类ActiveRecord::Migration::CommandRecorder并记录新方法及其反转版本。

activerecord/lib/active_record/migration/command_recorder.rb找到班级的定义。

答案 1 :(得分:1)

不确定是否需要做其他事情,但至少应该向ActiveRecord::Migration::CommandRecorder添加inverse_custom_thing方法

答案 2 :(得分:1)

在Rails 4中有一个reversible helper method,您可以这样使用:

def change
  do_custom_thing_on :users, :field1
  do_custom_thing_on :users, :field2
end

def do_custom_thing_on(table, field)
  reversible do |dir|
    dir.up { execute "some long sql to alter #{field} on #{table}"}
    dir.down { execute "some long sql to undo #{field} on #{table}"}
  end
end

答案 3 :(得分:0)

更改方法的主要目的是添加,重命名列但不删除。更改方法'知道'在回滚迁移时如何进行反向操作。因此,如果你想做一些不能删除的事情,只需在更改方法中执行,ActiveRecord就会自行撤销它。我想。

您可以从official documentation

获取更多信息