3.2 マイグレーション

マイグレーションを作成する

マイグレーションはdb/migrateディレクトリに保存されます。以下のコマンドでマイグレーションファイルを生成できます。

$ rails g migration AddViewsToPosts

# 結果
Running via Spring preloader in process 96646
      invoke  active_record
      create    db/migrate/20180615090131_add_views_to_posts.rb

20180615090131_add_views_to_posts.rbの中身

class AddViewsToPosts < ActiveRecord::Migration[5.2]
  def change
  end
end

マイグレーションで使えるメソッド

  • add_column
  • add_index
  • add_reference
  • add_timestamps
  • add_foreign_key
  • create_table
  • create_join_table
  • drop_table (ブロックを渡す必要あり)
  • drop_join_table (ブロックを渡す必要あり)
  • remove_timestamps
  • rename_column
  • rename_index
  • remove_reference
  • rename_table

マイグレーションの実行

$ rails db:migrate

# 結果
== 20180615090131 AddViewsToPosts: migrating ==================================
== 20180615090131 AddViewsToPosts: migrated (0.0000s) =========================

テーブルを追加する

マイグレーションを作成し、テーブルを追加していきます。

テーブル追加の方法

  1. Railsのモデルジェネレータを使う
  2. マイグレーションを作成しcreate_tableメソッドを使う

1. Railsのモデルジェネレータを使う

# Commentモデルを作成
# text型のcontentカラムとinteger型のuser_idを追加
$ rails g model Comment content:text user_id:integer

# 結果
Running via Spring preloader in process 97572
      invoke  active_record
      create    db/migrate/20180615091220_create_comments.rb
      create    app/models/comment.rb
      invoke    test_unit
      create      test/models/comment_test.rb
      create      test/fixtures/comments.yml

# マイグレーションを実行
$ rails db:migrate

== 20180615091220 CreateComments: migrating ===================================
-- create_table(:comments)
   -> 0.0014s
== 20180615091220 CreateComments: migrated (0.0016s) ==========================

2. マイグレーションを作成しcreate_tableメソッドを使う

# CreateCommentマイグレーションを作成
# text型のcontentカラムとinteger型のuser_idを追加
$ rails g migration CreateComment

# 結果
Running via Spring preloader in process 999
      invoke  active_record
      create    db/migrate/20180615092418_create_comment.rb

作成されたマイグレーションファイルを以下のように編集します。

db/migrate/20180615092418_create_comment.rb

class CreateComment < ActiveRecord::Migration[5.2]

  def change
    create_table :comments do |t|
      t.text :content
      t.integer :user_id
    end
  end
end
# マイグレーションを実行
$ rails db:migrate

# 結果
== 20180615091220 CreateComments: migrating ===================================
-- create_table(:comments)
   -> 0.0014s
== 20180615091220 CreateComments: migrated (0.0016s) ==========================

テーブル名を変更する

テーブル名を変更するにはrename_tableメソッドを利用します。

# RenameCommentsマイグレーションを作成
$ rails g migration RenameComments

# 結果
Running via Spring preloader in process 1995
      invoke  active_record
      create    db/migrate/20180615093418_rename_comments.rb

作成されたマイグレーションファイルを以下のように編集します。

db/migrate/20180615093418_rename_comments.rb

class RenameComments < ActiveRecord::Migration[5.2]
  def change
    # rename_table 現在のテーブル名, 新しいテーブル名
    rename_table :comments, :reactions
  end
end
# マイグレーションを実行
$ rails db:migrate

# 結果
== 20180615093418 RenameComments: migrating ===================================
-- rename_table(:comments, :reactions)
   -> 0.0016s
== 20180615093418 RenameComments: migrated (0.0017s) ==========================

テーブルを削除する

テーブルを削除するにはdrop_tableメソッドを利用します。

# DropReactionsマイグレーションを作成
$ rails g migration DropReactions

# 結果
Running via Spring preloader in process 2933
      invoke  active_record
      create    db/migrate/20180615093835_drop_reactions.rb

作成されたマイグレーションファイルを以下のように編集します。

db/migrate/20180615093835_drop_reactions.rb

class DropReactions < ActiveRecord::Migration[5.2]
  def change
    # drop_table(:テーブル名 [, オプション])
    drop_table :reactions
  end
end
# マイグレーションを実行
$ rails db:migrate

# 結果
== 20180615093835 DropReactions: migrating ====================================
-- drop_table(:reactions)
   -> 0.0014s
== 20180615093835 DropReactions: migrated (0.0015s) ===========================

カラムを追加する

テーブルにカラムを追加するにはadd_columnメソッドを利用します。

# AddPublishedAtToPostsマイグレーションを作成
$ rails g migration AddPublishedAtToPosts

# 結果
Running via Spring preloader in process 42449
      invoke  active_record
      create    db/migrate/20180615094848_add_published_at_to_posts.rb

作成されたマイグレーションファイルを以下のように編集します。

db/migrate/20180615094848_add_published_at_to_posts.rb

class AddPublishedAtToPosts < ActiveRecord::Migration[5.2]
  def change
    # add_column(テーブル名 カラム名, タイプ [, オプション])
    add_column :posts, :published_at, :datetime
  end
end
# マイグレーションを実行
$ rails db:migrate

# 結果
== 20180615094848 AddPublishedAtToPosts: migrating ============================
-- add_column(:posts, :published_at, :datetime)
   -> 0.0009s
== 20180615094848 AddPublishedAtToPosts: migrated (0.0012s) ===================

カラム名を変更する

テーブルのカラム名を変更するにはrename_columnメソッドを利用します。

# RenameViewsToPageViewsマイグレーションを作成
$ rails g migration RenameViewsToPageViews

# 結果
Running via Spring preloader in process 42449
      invoke  active_record
      create    db/migrate/20180615095928_rename_views_to_page_views.rb

作成されたマイグレーションファイルを以下のように編集します。

db/migrate/20180615095928_rename_views_to_page_views.rb

class RenameViewsToPageViews < ActiveRecord::Migration[5.2]
  def change
    # rename_column(テーブル名, 変更するカラム名, 新しいカラム名)
    rename_column :posts, :views, :page_views
  end
end
# マイグレーションを実行
$ rails db:migrate

# 結果
== 20180615095928 RenameViewsToPageViews: migrating ===========================
-- rename_column(:posts, :views, :page_views)
   -> 0.0086s
== 20180615095928 RenameViewsToPageViews: migrated (0.0086s) ==================

カラムを削除する

テーブルのカラムを削除するにはremove_columnメソッドを利用します。

# RemovePageViewsFromPostsマイグレーションを作成
$ rails g migration RemovePageViewsFromPosts

# 結果
Running via Spring preloader in process 42449
      invoke  active_record
      create    db/migrate/20180615100534_remove_page_views_from_posts.rb

作成されたマイグレーションファイルを以下のように編集します。

db/migrate/20180615100534_remove_page_views_from_posts.rb

class RemovePageViewsFromPosts < ActiveRecord::Migration[5.2]
  def change
    # remove_column(テーブル名, カラム名 [, 型, オプション])
    remove_column :posts, :page_views, :integer
  end
end
# マイグレーションを実行
$ rails db:migrate

# 結果
== 20180615100534 RemovePageViewsFromPosts: migrating =========================
-- remove_column(:posts, :page_views)
   -> 0.0220s
== 20180615100534 RemovePageViewsFromPosts: migrated (0.0351s) ================

カラムにインデックスを追加する

テーブルのカラムにインデックスを追加するにはadd_indexメソッドを利用します。

# AddIndexToCommentsマイグレーションを作成
$ rails g migration AddIndexToComments

# 結果
Running via Spring preloader in process 42449
      invoke  active_record
      create    db/migrate/20180615144015_add_index_to_comments.rb

作成されたマイグレーションファイルを以下のように編集します。

db/migrate/20180615144015_add_index_to_comments.rb

class AddIndexToComments < ActiveRecord::Migration[5.2]
  def change
    # add_index(テーブル名, インデックスを追加するカラム [, オプション])
    add_index :comments, :user_id
  end
end
# マイグレーションを実行
$ rails db:migrate

# 結果
== 20180615144015 AddIndexToComments: migrating ===============================
-- add_index(:comments, :user_id)
== 20180615144015 AddIndexToComments: migrated (0.0351s) ================

カラムからインデックスを削除する

テーブルのカラムにインデックスを削除するにはremove_indexメソッドを利用します。

# RemoveIndexFromCommentsマイグレーションを作成
$ rails g migration RemoveIndexFromComments

# 結果
Running via Spring preloader in process 42449
      invoke  active_record
      create    db/migrate/20180615144419_remove_index_from_comments.rb

作成されたマイグレーションファイルを以下のように編集します。

db/migrate/20180615144419_remove_index_from_comments.rb

class RemoveIndexFromComments < ActiveRecord::Migration[5.2]
  def change
    # remove_index(テーブル名 [, オプション])
    remove_index :comments, :user_id
  end
end
# マイグレーションを実行
$ rails db:migrate

# 結果
== 20180615142165 RemoveIndexFromComments: migrating ===============================
-- remove_index(:comments, :user_id)
== 20180615142165 RemoveIndexFromComments: migrated (0.0351s) ================

マイグレーションをロールバックする

$ rails db:rollbackコマンドで実行したマイグレーションを戻すことができます。

直前のマイグレーションをロールバックする

$ rails db:rollback

# 結果
== 20180615100534 RemovePageViewsFromPosts: reverting =========================
-- add_column(:posts, :page_views, :integer)
   -> 0.0012s
== 20180615100534 RemovePageViewsFromPosts: reverted (0.0033s) ================

直前のマイグレーションをロールバックする

複数回マイグレーションを戻したい場合はSTEPパラメータを指定することで可能です。

$ rails db:rollback STEP=2

# 結果
== 20180615095928 RenameViewsToPageViews: reverting ===========================
-- rename_column(:posts, :page_views, :views)
   -> 0.0089s
-- remove_column(:posts, :views, :integer)
   -> 0.0921s
== 20180615095928 RenameViewsToPageViews: reverted (0.1036s) ==================

== 20180615094848 AddPublishedAtToPosts: reverting ============================
-- remove_column(:posts, :published_at, :datetime)
   -> 0.0056s
== 20180615094848 AddPublishedAtToPosts: reverted (0.0059s) ===================

マイグレーションでSQLを実行する

executeメソッドを利用することによりマイグレーション内で生のSQL文を実行することができます。

# InsertDataToPostsマイグレーションを作成
$ rails g migration InsertDataToPosts

# 結果
Running via Spring preloader in process 42449
      invoke  active_record
      create    db/migrate/20180615145601_insert_data_to_posts.rb

作成されたマイグレーションファイルを以下のように編集します。

db/migrate/20180615145601_insert_data_to_posts.rb

class RemoveIndexFromComments < ActiveRecord::Migration[5.2]
  def change
    # execute SQL文
    execute 'INSERT INTO "posts" ("title", "created_at", "updated_at") VALUES ("This is title", "2018-06-15 15:00:50.866224", "2018-06-15 15:00:50.866224")'
  end
end
# マイグレーションを実行
$ rails db:migrate

# 結果
== 20180615145601 InsertDataToPosts: migrating ================================
-- execute("INSERT INTO \"posts\" (\"title\", \"created_at\", \"updated_at\") VALUES (\"This is title\", \"2018-06-15 15:00:50.866224\", \"2018-06-15 15:00:50.866224\")")
   -> 0.0011s
== 20180615145601 InsertDataToPosts: migrated (0.0013s) =======================

特定のマイグレーションのみを実行する

マイグレーションのステータスを確認

$ rails db:migrate:status

# 結果
Status   Migration ID    Migration Name
--------------------------------------------------
  up     20180615072046  Create posts
  up     20180615090131  Add views to posts
  up     20180615092418  Create comment
  up     20180615093418  Rename comments
  up     20180615093835  Drop reactions
 down    20180615094848  Add published at to posts
 down    20180615095928  Rename views to page views
 down    20180615100534  Remove page views from posts

statusupのものはマイグレーションが実行されているもの statusdownのものはマイグレーションが実行されていないもの

マイグレーションのIDを指定して実行

$ rails db:migrate:up VERSION=20180615094848

# 結果
== 20180615094848 AddPublishedAtToPosts: migrating ============================
-- add_column(:posts, :published_at, :datetime)
   -> 0.0012s
== 20180615094848 AddPublishedAtToPosts: migrated (0.0014s) ===================

環境ごとにマイグレーションを実行する

マイグレーションはデフォルトではdevelopment環境で実行されます。 環境を指定したい場合はRAILS_ENVパラメータで環境を指定することができます。

# test環境で実行
$ rails db:migrate RAILS_ENV=test

# production環境で実行
$ rails db:migrate RAILS_ENV=production

results matching ""

    No results matching ""