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) =========================
テーブルを追加する
マイグレーションを作成し、テーブルを追加していきます。
テーブル追加の方法
- Railsのモデルジェネレータを使う
- マイグレーションを作成し
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
status
がup
のものはマイグレーションが実行されているもの
status
がdown
のものはマイグレーションが実行されていないもの
マイグレーションの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