マイグレーション基礎知識のまとめ rails db:rollbackとカラムの追加/削除


はじめに

【この記事から得られる知識】
・マイグレーションについて
・rails db:rollbackの実行手順
・カラムの追加と削除の実行手順
・カラムがreferences型の場合の追加と削除の実行手順

【環境】
・macOS Catalina
・rails 6.0.0
・ruby 2.6.5

マイグレーションとは

・テーブルの設計図や仕様書のこと 
・データベースにテーブルを作成する際に重要な役割をもっている
 -マイグレーションファイルにカラムの型、カラム名、オプションの情報を記述する
 -情報を反映させるとテーブルの作成・変更ができる

マイグレーションの実行手順

①モデルを作成
②モデル作成時に生成されるマイグレーションファイル(db/migrate/2020~~~~.rb)に必要な情報を記述する

db/migrate/20201014123456_create_address.rb
class CreateAddresses < ActiveRecord::Migration[6.0]
  def change
    create_table :addresses do |t|
    # t.カラムの型 :カラム名,     オプション
      t.string :postal_code,    null: false
      t.string :city,           null: false
      t.string :address_line,   null: false
      t.string :phone_number,   null: false
      t.references :order,      null: false, foreing_key: true
      t.timestamps
    end
  end
end

③記述したテーブルのカラムを反映させるために作成中のアプリケーションのディレクトリにいることを確認した後ターミナルでrails db:migrateを実行

% rails  db:migrate

④ターミナルに以下のような記述があれば成功!

== 20XXXXXXXXXXXX CreateAddresses: migrating ======================================
-- create_table(:addresses)
   -> 0.0395s
== 20XXXXXXXXXXXX CreatePosts: migrated (0.0396s) =============================

念のためsequelproでも記述した情報が表示されていれるか確認する
※情報が反映されていない場合は更新ボタンをクリックする


せっかくrails db:migrateしたのにテーブルにミスがあった!

「どうしよう、、、」
「マイグレーションを編集したいっ!」ていうときありますよね。

しかし、一度実行すると再度実行できない仕組みになっています。
なぜかというと設計を履歴として残しあとでどのような変更をしたか確認できるようにするためです。

もしスペルミスでカラム名を変更したい場合であればわざわざ履歴に変更を残したくないですよね。

その場合はrails db:rollback コマンドを使いましょう。(反映済みの情報を差し戻すことができるため変更の履歴が残りません。)
それ以外の場合はカラムの追加/削除用のマイグレーションファイルを作成して変更を行いましょう。(新たにファイルを作成して変更をするため履歴が残ります。)

以下でこれらの説明をしたいと思います。


rails db:rollback 実行手順①~⑥

rails db:migrate:statusコマンドでマイグレーションファイルの状況を確認

% rails db:migrate:status

・実行するとマイグレーションの履歴が表示され、statusがupとdownで状況が表示される
・upは実行済み、downは修正可能の状態を意味する

# rails db:migrate:stauts 実行結果

database: アプリ名_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20201001015223  Create orders
   up     20201001092756  Create addresses
   up     20201014023427  Add id to addresses
   up     20201014030100  Add id to orders

rails db:rollbackを実行してup(実行済み)をdown(修正可能)にする

% rails db:rollback

③もう一度rails db:migrate:statusを実行しマイグレーションファイルの状況を確認する

database: アプリ名_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20201001015223  Create orders
   up     20201001092756  Create addresses
   up     20201014023427  Add id to addresses
  down    20201014030100  Add id to orders

④変更したいマイグレーションファイルのstatusがdownであることが確認できると今回の場合db/migrate/2020101430100_~~.rbのファイルを修正する
rails db:migrateを実行し修正内容を反映させる

% rails  db:migrate

⑥念のためsequelproでも記述した情報が表示されていれるか確認する
※情報が反映されていない場合は更新ボタンをクリックする

【補足情報】

任意のマイグレーションファイルをrollbackしdownの状態にしたい場合は
rails db:rollback STEP=数値(戻りたい箇所が下から数えて何番目か)というふうに記述し実行する
※一番下を1とする

# 下から2番目をrollbackしたい場合 
% rails db:rollback STEP=2

statusを確認すると下から2番目までdownになっていることが確認できる

database: アプリ名_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20201001015223  Create orders
   up     20201001092756  Create addresses
  down    20201014023427  Add id to addresses
  down    20201014030100  Add id to orders

後は同じようにマイグレーションファイルを修正しrails db:migrateを実行する

カラムの追加/削除 実行手順(パターン1, 2)

最初に前提の知識としてカラムの追加はadd_columnカラムの削除はremove_columnと記述する

    # カラムの追加
    add_column :users, :first_name, :string
    # カラムの削除
    remove_column :users, :last_name, :string

パターン1 : 順番に記述する方法

rail g migration ファイル名を実行
ファイル名はAddカラム名To追加先のテーブル名とする(ファイル名は任意のものでもいいが、Add~To~が後から見たときにわかりやすく定着したファイル名のつけ方になっている)

# nameカラムをUsersテーブルに追加する場合
% rails g migration AddNameToUsers

生成されるファイルの中身

db/migrate/20200000000000_add_names_to_users.rb
class AddNamesToUsers < ActiveRecord::Migration[6.0]
  def change 
  end
end

②新しく生成されたマイグレーションファイルに情報を記述する

db/migrate/20200000000000_add_names_to_users.rb
class AddNamesToUsers < ActiveRecord::Migration[6.0]
  def change
    add_column :users, :first_name, :string
    add_column :users, :last_name, :string
  end
end

rails db:migrateを実行する

% rails  db:migrate

パターン2 : ターミナルにまとめて記述する方法

rail g migration ファイル名 追加するカラム名:型を実行

# 追加するカラムの詳細情報までまとめ記述する
% rails g migration AddNameToUsers first_name:string last_name:string

生成されるファイルの中身(ファイルの中身が記述された状態でマイグレーションファイルが生成)

db/migrate/20200000000000_add_names_to_users.rb
class AddNamesToUsers < ActiveRecord::Migration[6.0]
  def change
    add_column :users, :first_name, :string
    add_column :users, :last_name, :string
  end
end

rails db:migrateを実行する

% rails  db:migrate

references型カラムの追加/削除 実行手順

状況:Ordersテーブルに外部キーとしてaddress_idを追加する

rails g migration ファイル名を実行する

# address_idカラムをOrdersテーブルに追加する場合
% rails g migration AddIdToOrders

②生成されたファイルに記述する

db/migrate/20201014000000_add_id_to_orders.rb
class AddIdToOrders < ActiveRecord::Migration[6.0]
  def change
    # 追加
    add_reference :orders, :address, foreign_key: true
    # 削除
    remove_reference :orders, :address, foreign_key: true
  end
end

追加のポイント
add_referenceであること
foreign_key: trueを記述すること(必要な場合のみ)
削除のポイント
remove_referenceであること

rails db:migrateを実行する

% rails  db:migrate

解説は以上です!!

想像より長くなってしまいましたがこの記事がお役に立てると幸いです。
慣れると簡単なのでぜひ習得してスムーズに開発が進められるようにしましょう!
それでは、最後までご覧いただきありがとうございました。

参考

https://qiita.com/kurawo___D/items/e3694f7a870a1cc4738e
https://freesworder.net/rails-column-add-remove/
https://gist.github.com/seak0503/84bfa6b37a0a6961c334