【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アプリのデバッグ《マルチデバイス篇》
# はじめに 近年のWebアプリはレスポンシブ対応が当たり前になっています。最低でもPCとスマートフォンに対応したデザイン、ときにはその中間のタブレットに対応したデザインなんかも作成する必要があります。 Webアプリの開発はPCを使って行う [...]
2021年5月23日 13:02
【Rails】Railsアプリのデバッグ《Better Errors篇》
# はじめに Railsアプリの開発中になんらかのエラーが発生すると、デフォルトでは以下のような画面が表示されます(画像をクリックすると拡大します)。 <a class="gallery" data-group="gallery" href [...]
2021年5月22日 19:42
【Rails】Railsアプリのデバッグ《byebug篇》
# はじめに Ruby on Railsに限りませんが、アプリの開発中にはエラーは付き物です。なにかしらのエラーが発生したときに、エラーの原因を特定しエラー箇所を修正することをデバッグと言います。Railsではデバッグの手助けとなる機能があらかじ [...]
2021年5月22日 15:30
【Rails】レンダリング(renderメソッド)でアンカー指定を行う
# はじめに 通常、Railsでアンカー付きのリクエストを発生させるには`redirect_to`を使います。 ```rb redirect_to root_path(anchor: 'target') ``` では、`rende [...]
2021年5月20日 10:47
【Rails】Bundler 2.2.x以降は開発者が適切なプラットフォームを追加する必要がある
# 事象 昔作ったRailsアプリを久しぶりに修正しデプロイしようとしたところ、以下のエラーが出力されました。 ```bash # 実行コマンド Running $HOME/.rbenv/bin/rbenv exec bundle ch [...]
2021年5月18日 16:18