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