【Rails】マイグレーションの書き方《作成・編集篇》

はじめに

データベースベンダーに依存することなくテーブルの作成やカラムの追加/削除などが行えるマイグレーションというActiveRecordの機能があります。マイグレーションはデータベースのスキーマ変更をバージョンとして管理するので、いつでもスキーマ変更を元に戻したり再実行できたりします。

本記事では、マイグレーションの作成・編集についてまとめています。

マイグレーションの作成

マイグレーションファイルはdb/migrate/ディレクトリに作成します。ファイルの名前はYYYYMMDDHHMMSS_Xxxxx.rbです。ファイル名の先頭はタイムスタンプで、アンダースコアを挟んでマイグレーションの名前が続きます。

マイグレーションファイルは手動で作成することも可能ですが、コマンドを実行して作成するほうが簡単です。コマンド実行で作成する方法には、モデル作成コマンドを使う方法とマイグレーション作成コマンドを使う方法の2種類があります。

モデル作成コマンド

モデル作成コマンドはモデルを作成するコマンドですが、モデルに対応したマイグレーションファイルも同時に作成します。モデル作成コマンドで作成できるのはテーブル作成を行うマイグレーションファイルだけです。

テーブル作成のマイグレーションファイルはモデル作成コマンドで作成し、その後のカラム追加/削除などのマイグレーションファイルはマイグレーション作成コマンドで作成するというのが一般的な流れかと思います。

$ rails generate model Article title:string content:text

モデルと同時に作成されたマイグレーションファイルの中身は以下の通りです。

class CreateArticles < ActiveRecord::Migration
  def change
    create_table :articles do |t|
      t.string :title
      t.text :content

      t.timestamps
    end
  end
end

t.timestampsは特殊なマクロで、created_atupdated_atという2つのカラムを追加します。この2つのカラムはActiveRecordによって自動的に管理されます。テーブルにレコードが追加されたらcreated_atに、レコードが更新されたらupdated_atにそれぞれタイムスタンプが自動で設定されます。

マイグレーション作成コマンド

マイグレーション作成コマンドは、その名の通りマイグレーションファイルを作成するためのコマンドです。

$ rails generate migration CreateArticles

YYYYMMDDHHMMSS_create_articles.rbというマイグレーションファイルが作成されます。作成されたマイグレーションファイルの中身は以下の通りです。このファイルにテーブルの作成やカラムの追加/削除を行うメソッドを定義していきます。

class CreateArticles < ActiveRecord::Migration
  def change
  end
end

マイグレーション作成コマンド実行時に、マイグレーション名をCreateXxxxxという形式にし、その後にカラム名と型を指定すると、指定したカラムを持つテーブルを作成するマイグレーションファイルが作成できます。指定するカラム名と型は複数指定できます。

$ rails generate migration CreateArticles title:string content:text

作成されたマイグレーションファイルの中身は以下の通りです。モデル作成コマンドで作成されたマイグレーションファイルと違い、自動でt.timestampsは追加されないので注意してください。

class CreateArticles < ActiveRecord::Migration
  def change
    create_table :articles do |t|
      t.string :title
      t.text :content
    end
  end
end

既存テーブルにカラムを追加するマイグレーションファイルを作成するには、マイグレーション名をAddXxxxxToYyyyyという形式にし、その後に追加するカラム名と型を指定します。

$ rails generate migration AddCategoryToArticles category:string

作成されたマイグレーションファイルの中身は以下の通りです。

class CreateArticles < ActiveRecord::Migration
  def change
    add_column :articles, :category, :string
  end
end

既存テーブルからカラムを削除するマイグレーションファイルを作成するには、マイグレーション名をRemoveXxxxxFromYyyyyという形式にし、その後に削除するカラム名と型を指定します。

$ rails generate migration RemoveCategoryFromArticles category:string

作成されたマイグレーションファイルの中身は以下の通りです。

class CreateArticles < ActiveRecord::Migration
  def change
    remove_column :articles, :category, :string
  end
end

マイグレーションの編集

モデル作成コマンドやマイグレーション作成コマンドで作成したマイグレーションファイルを手動で書き換えることができます。

changeメソッド

基本的にマイグレーションファイルは可逆的に記述する必要があります。テーブル作成後やカラム追加/削除後にそれらの変更を取り消したい場合、マイグレーションのロールバックを行います。このとき、マイグレーションファイルが可逆的に記述されていないと、ActiveRecordがマイグレーションをロールバックできません。

マイグレーションファイルを可逆的に記述する方法のひとつがchangeメソッドです。以下のようにchangeメソッドで囲まれたマイグレーションが可逆的になります。

class CreateArticles < ActiveRecord::Migration
  def change
    # テーブル作成やカラム追加/削除のマイグレーション
  end
end

changeメソッドがサポートしているマイグレーションは以下の通りです。

  • add_column
  • add_index
  • add_reference
  • add_timestamps
  • create_table
  • create_join_table
  • drop_table (ブロックのみ)
  • drop_join_table (ブロックのみ)
  • remove_timestamps
  • remove_reference
  • rename_column
  • rename_index
  • rename_table

これらのマイグレーション以外を記述している場合、代わりにreversibleメソッドを使います(今回は省略)。また、古い記述方法としてup/downメソッドを使う方法もありますが、ほとんどの場合changeメソッドで事足りるかと思います。

create_tableメソッド

create_tableメソッドはテーブルを作成するときに使います。実際にはモデル作成コマンドやマイグレーション作成コマンドで作成されたマイグレーションファイルをそのまま使うことがほとんどだと思うので、このメソッドを自分で書くことはまずないと思います。

create_tableメソッドは暗黙的にidという主キーを追加します。

create_table :articles do |t|
  t.string :title
  t.text :content
end

change_tableメソッド

change_tableメソッドは既存テーブルを変更するときに使います。change_tableメソッド内で各カラムに対して様々な変更を行うことができます。以下の例では、articlesテーブルにsubtitleカラムを追加し、categoryカラムを削除し、contentカラムの名前を変更しています。

change_table :articles do |t|
  t.string :subtitle
  t.remove :category
  t.rename :content, :body
end

まとめ

マイグレーションで行った変更は必ずマイグレーションで戻す必要があります。それを忘れて手動で操作なんかしてしまうと、今度はマイグレーションの整合性を正すという余計な作業が発生してしまいます。そうならないためにも、しっかりとマイグレーションファイルの作成・編集の仕方を覚えておく必要があります。

本記事を参考にして、マイグレーションファイルの作成・編集の仕方を覚えていただければと思います。

関連記事

【Rails】M1チップ搭載MacでRuby on Railsの開発環境構築
# はじめに M1チップ搭載MacにRuby on Railsの開発環境を構築する手順を記載します。 - MacBook Air (M1, 2020) - macOS Monterey 12.3.1 # Homebrew ## [...]
2022年5月5日 11:56
【Rails】Rakeタスクの基本情報と作成・実行方法
# はじめに Railsには標準でRakeというGemが同梱されています。RakeはRubyで実装されたMake(UNIX系のOSで使用できるコマンド)のようなビルド作業を自動化するツールです。Ruby Make、略してRakeというわけですね。 [...]
2022年3月7日 22:12
【Rails】モデルに外部キーを設定する方法とよく起こるエラー内容について
# はじめに Railsでモデルに外部キーを設定する方法について説明します。 # モデルに外部キーを設定する ## リレーションシップ 今回は1つのブログ記事は複数のコメントを持つ1対多のリレーションシップを例に説明します。現在は` [...]
2022年2月10日 14:18
【Rails】Capybaraのfill_inメソッドを実行すると「既存レコードの内容+指定した内容」がセットされる事象の原因と対処【RSpec】
# はじめに RSpec + Capybaraを使用して、Railsアプリの統合テストを実装しています。とあるモデルの編集画面において、入力フォームの内容を書き換えた上で送信し、レコードが更新されることを確認します。 入力フォームの内容を書 [...]
2022年1月27日 21:22
【Rails】GitHubのセキュリティアラートで発見された脆弱性を解消する方法
# はじめに GitHubにはセキュリティアラートという機能があります。セキュリティアラートはリポジトリに含まれるライブラリやパッケージの脆弱性を定期的にチェックし、脆弱性のあるライブラリやパッケージが発見されたらアラートで知らせてくれるという機 [...]
2022年1月16日 10:36