我发现自己必须在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
但这样做是为了让变化“可逆”逃脱了我。
答案 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就会自行撤销它。我想。
获取更多信息