マイグレーション作成時にchangeメソッドではなくup/downメソッドを使う場面(Rails)

【結論】

マイグレーションを作成する場合、up/downメソッドを利用する方法と、changeメソッドを利用する方法が存在する

up/downメソッドはマイグレーション時とロールバック時の両方の処理内容を定義する必要があるのに対して、changeメソッドはマイグレーション時の処理だけ定義すれば、ロールバック時の処理は自動で判断する

changeメソッドが認識できないマイグレーション定義は、up/downメソッドを利用する必要がある

【目次】

【本題】

マイグレーションの作成方法

Railsマイグレーションの作成方法は、大きく分けて二種類存在します。

それは、up/downメソッドを利用する方法と、changeメソッドを利用する方法です。

up/downメソッド

up/downメソッドは、upマイグレーション時の処理を、downロールバック時の処理を定義する方法です。

例えば、Postテーブルのnameカラムを追加したい場合、up/downメソッドでは以下のように定義します。

class ChangeColumnPost < ActiveRecord::Migration 
  def up
    add_column :post, :name, :string
  end

  def down
    remove_column :post, :name
  end
end 

このように記述することで、マイグレーション時はカラム追加の処理が実行され、ロールバック時にはカラム削除の処理が実行されます。

changeメソッド

changeメソッドは、マイグレーション時の処理だけ定義する方法です。

先程と同様に、Postテーブルのnameカラムを追加したい場合、changeメソッドでは以下のように定義します。

class ChangeColumnPost < ActiveRecord::Migration 
  def change
    add_column :post, :name, :string
  end
end 

ロールバック時の処理が定義されていませんが、ロールバックを実行する際は、マイグレーション定義から自動的に判断して実行してくれます。

up/downメソッドを利用するケース

この様に、changeメソッドの方がup/downメソッドより簡潔に処理内容が記述できるので、changeメソッドを使用した方が良いでしょう。

では、up/downメソッドはいつ使用するのかと言うと、changeメソッドがロールバックの処理を認識できないマイグレーション定義を利用する場合に用います。

現状、changeメソッドがサポートされているマイグレーション定義は以下の通りです。

add_column
add_foreign_key
add_index
add_reference
add_timestamps
change_column_default (:fromと:toの指定は省略できない)
change_column_null
create_join_table
create_table
disable_extension
drop_join_table
drop_table (ブロックを渡さなければならない)
enable_extension
remove_column(型を指定しなければならない)
remove_foreign_key(2番目のテーブルを指定しなければならない)
remove_index
remove_reference
remove_timestamps
rename_column
rename_index
rename_table

なお、change_tableを利用する場合は、ブロックでchange・change_default・removeが呼び出されていると、changeメソッドでロールバックの処理が識別できません。

参考情報

Active Record マイグレーション - Railsガイド

ActiveRecord::Migration::CommandRecorder