【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】Paranoiaを使用した論理削除(ソフトデリート)
# はじめに Paranoiaは、Railsアプリケーションで論理削除(ソフトデリート)を実現するためのGemです。 論理削除は、データベースのレコードを物理的に削除するのではなく、削除フラグを設定することで「削除済み」とみなす方法です。こ [...]
2024年7月20日 21:33
【Rails】activerecord-multi-tenantを使用したマルチテナントアプリケーションの作成
# はじめに マルチテナントアプリケーションでは、複数の顧客(テナント)が同じアプリケーションを利用するため、データの分離が必要です。 activerecord-multi-tenantは、このようなマルチテナント環境をサポートするための便 [...]
2024年7月18日 16:50
【Rails】RubyとRailsにおけるattr_reader, attr_writer, attr_accessorの概念と使用方法
# はじめに RubyとRailsの開発において、`attr_reader`,`attr_writer`,`attr_accessor`は非常に便利なメソッドです。これらは、クラス内でインスタンス変数に対するゲッターおよびセッターメソッドを簡単に [...]
2024年7月17日 18:11
【Rails】RubyとRailsにおけるyieldの概念と使用方法
# はじめに RubyとRailsにおける`yield`は、メソッドやテンプレートの中で動的にコードブロックを実行する能力を提供し、これによってコードの再利用性と拡張性が大幅に向上します。本記事では、RubyとRailsにおける`yield`の概 [...]
2024年7月17日 13:15
【Rails】AASMを使用してオブジェクトの状態遷移を効率的に管理
# はじめに Railsアプリケーションにおいて、オブジェクトの状態管理は重要な課題の一つです。AASM (Acts As State Machine) gemは、複雑な状態遷移を効率的に管理します。本記事では、AASMの基本的な使い方を解説して [...]
2024年7月16日 18:00
【Rails】RSpec + Swagger + rswagでアプリケーションのAPIをテストおよびドキュメント化する方法
# はじめに Railsアプリケーションの開発において、APIのテストとドキュメント化は重要な要素です。 RSpecはテストフレームワークとして広く利用されており、SwaggerはAPIの設計とドキュメント化を支援します。これらを統合するr [...]
2024年7月16日 14:27
【Rails】mailcatcherを使用して開発環境でメール送信をテストする方法
# はじめに mailcatcherは、開発環境でのメール送信をキャプチャするためのツールです。ローカルで送信されたメールをブラウザ上で簡単に確認できるようにします。mailcatcherをRailsアプリケーションで使用する方法について説明しま [...]
2024年7月15日 16:37
【Rails】impressionistを使用してページビューやクリック数を追跡する方法
# はじめに impressionist Gemを使用してRailsアプリケーションでページビューやクリック数を追跡する方法について説明します。 # 実装方法 ## impressionist Gemのインストール まず、impre [...]
2024年7月15日 14:18