【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】Railsアップグレードまとめ
# はじめに Ruby on Railsに限らず、何らかのフレームワークを使ってWebシステムを構築している場合、フレームワークのアップグレード作業は避けて通れません。 一般的にフレームワークはバージョン毎にEOL (End of Life [...]
2022年10月1日 14:32
【Rails】ユーザー登録時に行うメールアドレス認証機能の実装方法
# はじめに ユーザー登録/解除やログイン/ログアウトといった認証機能の導入に「devise」というGemを使っている人は多いと思います。「devise」では以下のように記述するだけで、ユーザー登録時に確認メールを送付しメールアドレス認証を行う機 [...]
2022年9月24日 14:24
【Rails】モデルに列挙型(enum)を定義し、使いこなす方法
# はじめに Railsはモデルでカラム名と同名の列挙型(enum)を定義することで、カラムと列挙型の変数を紐付けることができます。カラムと列挙型の変数を紐付けると、カラムに対して様々な便利な使い方ができるようになります。 本記事では、モデ [...]
2022年9月3日 10:29
【Rails】RailsでCORSとPreflight requestの設定を行う方法
# はじめに RailsアプリをAPIサーバーとして構築するには、CORS (Cross-Origin Resource Sharing)と Preflight requestの設定を行う必要があります。APIサーバーは外部からの要求に対して処理 [...]
2022年8月27日 10:44
【Ruby】Bundlerを使ってRubyGemsを作成/公開する方法
# はじめに Bundlerを使ってRubyGemsを作成および公開する方法について説明します。Bundlerを使わずにRubyGemsを作成/公開する方法については以下の記事を参照してください。 <iframe class="hatena [...]
2022年7月12日 23:18
【Ruby】RubyGemsを作成/公開する方法
# はじめに RubyGemsを作成および公開する方法について説明します。Bundlerを使ってRubyGemsを作成する方法については以下の記事を参照してください。 <iframe class="hatenablogcard" style [...]
2022年7月11日 21:52
【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