migration的reversible方法
跟踪一个简单的reversible
class TestReversible < ActiveRecord::Migration[5.1]
def change
binding.trace_tree(htmp: 'mig/reversible') do
reversible do |dir|
dir.up{ puts 'up' }
dir.down{ puts 'down' }
end
end
end
end
调用栈如下
源码如下
# activerecord-5.1.4/lib/active_record/migration.rb
ReversibleBlockHelper = Struct.new(:reverting) do
def up
yield unless reverting
end
def down
yield if reverting
end
end
def reversible
helper = ReversibleBlockHelper.new(reverting?)
execute_block { yield helper }
end
非常简单,就是rails/rake命令使用的migrate/up/rollback/down,会保存到reverting?实例变量中(之前分析过),然后遇到reversible块时,再生成一个类似Migration的ReversibleBlockHelper,于是,就如同调用Migration的up/down一样,ReversibleBlockHelper会根据reverting?而决定调up还是down
适合于想在Migration里写change,但又有少部分操作是rails不提供inverse_of,或者改数据,或者特定于数据库语法的场景