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 ===================================== |
実行結果を確認する
dbconsoleを使って、booksテーブルが存在しているか確認してみましょう。
【実行コード】
rails dbconsole
.tables
実行結果として、以下のようにbooksテーブルが表示されたでしょうか。
【実行結果】
ar_internal_metadata books schema_migrations
テーブル作成を確認できたら、以下のコードを実行して、作成されたテーブルの内容を確認しましょう。
実行するコード |
---|
PRAGMA TABLE_INFO(books); |
0|id|integer|1||1 |
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 #実行結果確認後、コンソールを抜ける↓ .exit |
【実行結果】0|id|integer|1||1 |
環境を指定して実行する
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 |
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機能についてサンプルコードを利用して動きを確認してみましょう。