マイグレーションファイルを作成すると自動でchangeメソッドが定義された状態のファイルが生成されます。
class AddNameToClient < ActiveRecord::Migration[6.1]
def change
end
end
changeメソッドはとても便利で、テーブルの構造(スキーマ)を過去の状態に戻すロールバック(rails:rollback)を行ったときに、Railsが自動でchangeメソッドと逆の処理を行ってくれます。
ですが、changeメソッドが使えるマイグレーション定義は add_column
やadd_index
など一部に限られています。
それ以外のchange_columnn
などのマイグレーション定義でロールバックを行うと、次のようなエラーが発生し、ロールバックすることができません。
ここでは、changeメソッドが使える定義の一覧をまとめています。
changeメソッドが使える定義一覧
ロールバック(rollback)を実行したときに、changeメソッドで自動逆戻し可能なマイグレーション定義は次になります。
基本的には、add_〇〇に対して、逆となるremove_〇〇 が用意されている定義など、機械的に逆処理が行えるもののみ該当します。
定義 | 内容 | 実例 |
---|---|---|
add_column | カラムを追加 | add_column :users, :picture, :binary, limit: 2.megabytes |
add_foreign_key | 指定したテーブルに外部キー制約を追加 | add_foreign_key :articles, :authors |
add_index | 指定したテーブルにインデックスを追加 | add_index :users, :name |
add_reference | 既存のテーブルにリファレンスを追加 | add_reference(:products, :supplier, index: { unique: true }) |
add_itemstamps | タイムスタンプを追加 | add_timestamps :suppliers, null: true |
change_column_default | カラムの初期値を設定 (:fromと:toの指定は省略できない) | change_column_default(:suppliers, :qualification, ‘new’) |
chnage_column_null | NULL制約の追加または削除 | change_column_null(:users, :nickname, false) |
create_join_table | 2つのテーブルを結合して新しいテーブルを作成 | create_join_table(:assemblies, :parts, options: ‘ENGINE=InnoDB DEFAULT CHARSET=utf8’) |
create_table | テーブルを作成 | create_table :suppliers, options: ‘ENGINE=InnoDB DEFAULT CHARSET=utf8’ |
drop_join_table | 結合テーブルを削除 | drop_join_table(:assemblies, :parts) |
drop_table | 指定したテーブルを削除(ブロックで指定した場合のみ) | drop_table :products |
remove_column | 指定したテーブルのカラムを削除(型の指定必須) | remove_column :users, :description, :string, limit: 20 |
remove_foreign_key | 外部キーの削除(2番目のテーブルを指定しなければならない) | remove_foreign_key :accounts, column: :owner_id |
remove_index | 指定したテーブルのインデックスを削除 | remove_index :accounts, column: :branch_id |
remove_reference | 既存のテーブルのリファレンスを削除 | remove_reference(:products, :user, index: true) |
remove_timestamps | 既存のテーブルのcreated_atとupdated_atを削除 | remove_timestamps(:users) |
rename_column | 指定したテーブルのカラム名を変更 | rename_column :suppliers, :description, :name |
rename_index | 指定したテーブルのインデックスを変更 | rename_index :people, ‘index_people_on_last_name’, ‘index_users_on_last_name’ |
rename_table | 指定したテーブルの名前を変更 | rename_table :now_table, :new_table |
ブロックでchange、change_default、removeが呼び出されない限り、change_tableもロールバック可能です。
remove_columnは、3番目の引数でカラムの型を指定すればロールバック可能になります。元々のカラムオプションも指定しておかないと、ロールバック時にRailsがカラムを再作成できなくなります。
https://railsguides.jp/active_record_migrations.html
また、命名規則に沿って、rails g migration
を行ったときに、自動でchangeメソッドが記述されるものは、ロールバック時に逆戻しができます。
(参考)【Rails】テーブルやカラムの追加・名前の変更・削除・データ型を変更する方法を実例で解説
ロールバック時にエラーが発生したときの対処法
上記以外のマイグレーション定義でエラーが発生した場合は、マイグレーションファイルのメソッドを、次の2つのどちらかに変更することで、エラーを回避することができます。
- upメソッドとdownメソッドを使う
- reversibleメソッドを使う
詳細については下記記事をご参考ください。
【Rails】エラー対処法:This migration uses change_column, which is not automatically reversible.
drop_tableのロールバック時にエラーが発生したときの対処法
drop_tableはchangeメソッドで使用可能なマイグレーション定義の一つですが、ブロックで記述していない場合はエラーが発生します。
対処法は以下があります。
- ブロック形式で記述する
- upメソッドとdownメソッドを使う
- ロールバックを許可しない
- reversibleメソッドを使う
詳細については下記記事をご参考ください。