在Rails迁移中使用up / down与change / reversible方法有什么区别吗?

时间:2015-06-01 06:55:57

标签: ruby-on-rails migration

在Rails迁移中,如果我这样做,它会有什么不同:

def up
  foo
end

def down
  bar
end

或者这个:

def change
  reversible do |direction|
    direction.up { foo }
    direction.down { bar }
  end
end

我认为如果部分迁移包括可逆方法,例如create_tableadd_column等,则使用更改方法会更好。除此之外,是否有任何区别?

2 个答案:

答案 0 :(得分:4)

正如你所展示的那样,没有任何优势。主要优点是很多时候你根本不需要编写down方法/块,例如

class SomeMigration < ActiveRecord::Migration
  def change
    create_table :articles do |t|
      ...
    end
  end
end

reversible方法主要用于迁移的一小部分,即activerecord不知道如何反转(例如原始SQL语句)

答案 1 :(得分:1)

更改方法适用于可轻松派生可逆逻辑且ActiveRecord迁移可轻松处理的许多情况。但是,在某些情况下,您可能需要在迁移过程中执行某些特定操作,以确保它可以正常运行。可能还有一些复杂的事情是不可逆转的迁移。 见Rails: Is it bad to have an irreversible migration?

在这种情况下,最好使用up down方法,但也不会检查迁移的当前方向是否只是reverting?

以下是您可以使用此代替2种上/下方法的示例。在此示例中,还有一个复杂的数据方法未显示,如果没有条件逻辑,则会导致迁移错误。我已经因为与您的问题无关而被忽略了:

def change
  add_column :languages, :iso_639_2t, :string
  add_column :languages, :iso_639_2b, :string
  add_column :languages, :iso_639_3, :string
  add_index :languages, :iso_639_2t
  unless reverting?
    ActiveRecord::Base.connection
    .execute("ALTER SEQUENCE languages_id_seq RESTART WITH #{Language.count+1}")
  end
end

例如,如果通过migration_data gem在迁移中使用复杂数据操作,则可能需要添加def check_data方法,并在data_check失败时引发异常。

如果迁移真的不可逆转(破坏数据),您可能还想使用向上/向下例如:

def up
  remove_column :signup, :date
end

def down
  raise ActiveRecord::IrreversibleMigration, "Date field dropped in previous migration. Data unrecoverable"
end