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
浙公网安备 33010602011771号