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

 

posted on 2016-06-17 16:03  c3tc3tc3t  阅读(677)  评论(0编辑  收藏  举报