rails中两种回滚-reversible和revert区别【更新】
1 通常迁移内容写在change方法中 ,但是有些迁移内容不能自动通过执行rake:rollback回滚, 所以在迁移文件里要使用 reversible 方法,告诉rails如何回滚例如下面
# coding: utf-8 class ExampleMigration < ActiveRecord::Migration def change create_table :distributors do |t| t.string :zipcode end reversible do |dir| dir.up do # add a CHECK constraint execute <<-SQL ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5) NO INHERIT; SQL end dir.down do #这里写上如何回滚 execute <<-SQL ALTER TABLE distributors DROP CONSTRAINT zipchk SQL end end add_column :users, :home_page_url, :string rename_column :users, :email, :email_address end end
所以 reversible 的down调用,是在你执行rake db:rollback里 ,说白了,就是当你执行rollback的时候,reversible里的down起作用,同时up,down和reversible是等价的功能,就是up,down是分开写 ,reversible的down也是在rollback调用的时候调用,up在migration执行时起作用
2 revert是在你执行 是在你执行 rake db:migrate 同时,取消上一个迁移文件的操作,这里需要传递上一个迁移文件的类名给revert,同时引用上一个迁移文件 require_relative 'xxx.rb',
require_relative '2012121212_example_migration' #相对引用上一个迁移文件
class FixupExampleMigration < ActiveRecord::Migration def change revert ExampleMigration #这里是上一个迁移文件的类名,这时,如果上一个迁移文件change里代码可以自动回滚就自动回滚,如果里面有up,down或者reversible就调用这三个来回滚 create_table(:apples) do |t| t.string :variety end end end
3 当你要撤销的迁移文件里没有使用reversible或者up,down时,你也不想执行rollback回滚,这时 revert也可以传递一个块,这样 你可以在块里面使用reversible进行具体操作,
class DontUseConstraintForZipcodeValidationMigration < ActiveRecord::Migration def change revert do # copy-pasted code from ExampleMigration reversible do |dir| dir.up do # add a CHECK constraint execute <<-SQL ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5); SQL end dir.down do execute <<-SQL ALTER TABLE distributors DROP CONSTRAINT zipchk SQL end end # The rest of the migration was ok end end end
----update---
最近看rails guide指南又对这两个方法有了新的思考
revert 就是对原来的代码进行rollback,但是只需要贴上原来的代码,不需要手动将里面的操作人为的反转例如下面,3行到11行,就是原来操作,这样使用rails db:migrate进行rollback,
1 def change 2 revert do 3 # copy-pasted code from ExampleMigration 4 reversible do |direction| 5 direction.up do 6 add_column :apples, :address, :string 7 end 8 direction.down do 9 remove_column :apples, :address 10 end 11 end 12 13 # The rest of the migration was ok 14 end 15 end
如果用reversible的话,就需要将里面的逻辑反转,如下,4行内容是线先删除,而不是原来的操作
1 def change 2 reversible do |direction| 3 change_table :apples do |_t| 4 direction.up { remove_column :apples, :address } 5 direction.down { add_column :apples, :address, :string } 6 end 7 end 8 end