PR

Railsのmigrationファイル作成から実行まで方法解説

Ruby・Rails

Railsによるアプリケーション開発では、migrationを使ってデータベーステーブルの作成や調整を簡単に行うことができます。本記事では、サンプルを交えながら、Railsのmigrationの使い方と効果を解説します。

migrationとは

migrationとは、IT用語で、「プログラムやデータ、OSなどの環境やプラットフォームを移行、変換すること」を意味します。Windowsの移行は「Windowsマイグレーション」、データベースの移行は「データベースマイグレーション」と呼ばれています。

Ruby on Rails(以下Railsと記載)のmigrationは、Active Recordの機能の1つで、RubyのDSLを使っています。

migrationのメリット

Railsではmigrationにより、データベーススキーマを長期にわたって安定して発展・増築し続けることができます。Railsでは、migration機能のおかげで、Rubyで作成されたmigration用のドメイン固有言語(DSL) により、テーブルの変更を簡単に記述することができます。

実装者のデータベース知識に関わらず、スキーマを変更するためのSQLをmigration機能が作成してくれます。

Railsのmigrationファイルの作成から実行まで解説

Railsのmigrationは、作成するとdb/migrateディレクトリに保存されます。Railsでは、1つのmigrationクラスに1つのファイルが対応します。

migrationファイル名は、「YYYYMMDDHHMMSS_xxxxxxx.rb」という形式で生成されます。ファイルの命名規則として、「ファイルの生成日時+生成時に指定したmigrationクラス名」で構成されます。

migrationファイルを作成する

さっそくmigrationクラスを作成してみましょう。サンプルとしてbooksテーブルを作成し、カラムの追加・削除を行うことを想定して進めていきます。

【基本記述コード】
rails generate migration クラス名

クラス名は任意ですが、わかりやすいように「処理+対象」という形で命名するのが一般的です。authorカラム追加クラスなら「AddAuthor」といった具合です。

テーブル作成用のmigrationクラス作成

booksテーブルを作成するRailsのmigrationクラスを作ってみましょう。クラス名は「CreateBook」とします。

【サンプルコード】
rails generate migration CreateBook name:string

「name:string」は、テーブルに作成するカラムを指定しています。カラムを指定せずにmigrationクラスを作ることもできます。

yyyymmddhhmmss_create_book.rb内のコード

migraionファイルを生成すると、以下のコードが自動生成されます。Railsでmigration作成時に、カラムを指定しない場合は、「def change」は空で生成されます。

【生成されるコード】
class CreateBook < ActiveRecord::Migration[5.1]
def change
create_table :books do |t|
t.string :name
end
end
end

サンプルコードを使ってmigrationの動作確認

作成したbooksテーブルを操作するmigrationクラスを作ってみましょう。migrationの動作確認として、テーブルが変更される過程を見るため、以下の操作を行うmigrationクラスをサンプルとして作成してみます。

①カラム追加
②カラム名変更
③カラム削除
④カラム追加

サンプルコード
rails generate migration AddStringColToBook
rails generate migration RenameFromStringColToAuthorOnBook
rails generate migration RemoveAuthorFromBook
rails generate migration AddIntegerColToBook

サンプルコード①のコード

①のコマンドを実行すると、db/migrateディレクトリに、yyyymmddhhmmss_add_string_col_to_book.rbが生成されます。このファイルには以下のコードが自動生成されています。

class AddStringColToBook < ActiveRecord::Migration[5.1]
def change
add_column :books, :string_col, :string
end
end

サンプルコード②のコード

②のコマンドを実行すると、db/migrateディレクトリに、yyyymmddhhmmss_rename_from_string_col_to_author_on_book.rbが生成されます。このファイルには以下のコードが自動生成されています。

class RenameFromStringColToAuthorOnSample < ActiveRecord::Migration[5.1]
def change
rename_column :books, :string_col, :author
end
end

サンプルコード③のコード

③のコマンドを実行すると、db/migrateディレクトリに、yyyymmddhhmmss_remove_author_from_book.rbが生成されます。このファイルには以下のコードが自動生成されています。

class RemoveAuthorFromBook < ActiveRecord::Migration[5.1]
def down
add_column :books, :author, :string
end
def up
remove_column :books, :author
end
end

サンプルコード④のコード

④のコマンドを実行すると、db/migrateディレクトリに、yyyymmddhhmmss_add_integer_col_to_book.rbが生成されます。このファイルには以下のコードが自動生成されています。

class AddIntegerColToBook < ActiveRecord::Migration[5.1]
def change
add_column :books, :integer_col, :integer
end
end

テーブルが存在していないことを確認しておく

作成したmigrationクラスを使って、テーブルの作成とテーブル操作の確認をします。テーブルを作成することから始めるので、以下のコマンドを実行して、作成しようとしているテーブルが存在していないことを確認しておきます。

【実行コード】
rails dbconsole
.tables

実行結果にbooksテーブルが表示されないことを確認したら、「.exit」を実行して、コンソールを抜けます。

migrationファイルを実行する

ここまで作成したRailsのmigrationクラスを、実際に実行してみましょう。実行には、migrateコマンドを使用します。

【実行コード】
rails db:migrate
実行結果イメージ
== yyyymmddhhmmss CreateBook: migrating =====================================
-- create_table(:books)
-> 0.0041s
== yyyymmddhhmmss CreateBook: migrated (0.0042s) ============================

== yyyymmddhhmmss AddStringColToBook: migrating =============================
-- add_column(:books, :string_col, :string)
-> 0.0011s
== yyyymmddhhmmss AddStringColToBook: migrated (0.0012s) ====================

== yyyymmddhhmmss RenameFromStringColToAuthorOnBook: migrating =============
-- rename_column(:books, :string_col, :author)
-> 0.0057s
== yyyymmddhhmmss RenameFromStringColToAuthorOnBook: migrated (0.0059s) ====

== yyyymmddhhmmss RemoveAuthorFromBook: migrating ==========================
-- remove_column(:books, :author)
-> 0.0054s
== yyyymmddhhmmss RemoveAddressFromBook: migrated (0.0057s) =================

== yyyymmddhhmmss AddIntegerColToBook: migrating ============================
-- add_column(:books, :integer_col, :integer)
-> 0.0009s
== yyyymmddhhmmss AddIntegerColToBook: migrated (0.0010s) ===================

実行結果を確認する

dbconsoleを使って、booksテーブルが存在しているか確認してみましょう。

【実行コード】
rails dbconsole
.tables

実行結果として、以下のようにbooksテーブルが表示されたでしょうか。

【実行結果】
ar_internal_metadata books schema_migrations

テーブル作成を確認できたら、以下のコードを実行して、作成されたテーブルの内容を確認しましょう。

実行するコード
PRAGMA TABLE_INFO(books);
0|id|integer|1||1
1|name|varchar|0|NULL|0
2|integer_col|integer|0||0

dbconsoleを抜ける

テーブルが作成され、一連のmigrationが実行されたため、最終的なテーブルは、id、name、inteegr_colというカラムで構成されています。ここまで確認できたところで、「.exit」を実行し、dbconsoleを抜けておきましょう。

migrationファイルを途中まで反映する方法

migrateコマンドを実行すると、すべてのmigrationクラスが反映されたテーブルになりました。サンプルで作成した「author」カラムの追加なども確認するため、migrationファイルを途中のファイルまでに限定して実行することも可能です。

ここでは、途中までのmigrationファイルまでを実行する方法を紹介します。

VERSIONオプションを使ってmigrationを実行する

migrationファイルを途中まで実行する場合は、以下のコードを実行します。

【コード記述例】
bin/rake db:migrate VERSION=0
bin/rake db:migrate VERSION=yyyymmddhhmmss

「VERSION=0」を指定して、すべてのmigrationファイルを未反映の状態に戻します。次に、実行したい順番のmigrationファイルの年月日日時部分を指定します。

テーブルの構造を確認
【コマンド実行】
rails dbconsole
PRAGMA TABLE_INFO(books);

#実行結果確認後、コンソールを抜ける↓
.exit
【実行結果】
0|id|integer|1||1
1|name|varchar|0|NULL|0
2|author|varchar|0|NULL|0

環境を指定して実行する

rails db:migrateを実行すると、db/development.sqlite3にあるdevelopment環境に対してmigrationファイルが実行されます。

Railsでは、config/database.ymlでデータベース環境の設定が可能です。RAILS_ENVオプションを指定し、test環境やproduction環境に対してmigrationファイルを実行できます。

RAILS_ENVの設定
test環境に対して設定:/rails db:migrate RAILS_ENV=test
production環境に対して設定:/rails db:migrate RAILS_ENV=production

status欄で適用の確認を行う

Railsでmigrationファイルの適用状態を確認する方法も覚えておきましょう。

【実行コード】
bin/rake db:migrate:status

コード実行結果として、Status欄に「up」と表示されているmigrationファイルが、データベースに適用済みです。Status欄が「down」と表示されているmigrationファイルは未適用です。

実行結果イメージ
Status Migration ID Migration Name
--------------------------------------------------
up 20180704015653 Create book
up 20180704015654 Add string col to book
up 20180704015655 Rename from string col to author on book
down 20180704015656 Remove author from book
down 20180704020017 Add integer col to book

migrationファイルのupメソッドを実行する

Railsでは未適用のmigrationは、upメソッドで適用することができます。ここでは、4つ目のカラムを削除するmigrationは未適用のまま、5つ目のカラム追加のmigrationのみ適用してみます。

【実行コード】
rails db:migrate:up VERSION=yyyymmddhhmmss

「yyyymmddhhmmss」は、5つ目のmigrationファイルの年月日日時部分を指定します。

migrationファイルのdownメソッドを実行する

status確認で、upメソッドでmigrationが適用されたことを確認できたら、再度5つ目のmigrationを未適用に戻しましょう。Railsでは、downメソッドを使用します。

【実行コマンド】
rails db:migrate:down VERSION=yyyymmddhhmmss

データベースを一度削除して初期化する方法

データベースの編集が増えた場合など、一旦、データベースを削除してから、すべてのmigrationファイルを適用し直すことがあります。Railsではresetコマンド1つでテーブル削除とmigrationファイルの全適用ができます。

【実行コマンド】
rails db:migrate:reset

ロールバックでmigrationを巻き戻す

Railsのmigrationを利用していれば、rails db:rollbackを使うことで、データベースの構造を一つ前の状態に戻せます。以下のコマンドを実行してみましょう。

【実行コマンド】
rails db:rollback

statusを使って状態を確認してみましょう。最後のmigrationだけ「down」状態に戻っている確認ができるはずです。

Railsのmigrationは使いやすい

Railsのmigrationは、データベースの知識が少しあるだけでも、簡単にテーブルの定義変更などを行えて、開発効率を上げてくれることでしょう。

Railsの環境ができたら、migration機能についてサンプルコードを利用して動きを確認してみましょう。

タイトルとURLをコピーしました