Posted at

Railsのマイグレーションについて初心者なりに勉強してみた

Railsをたまに触っているのですが、ちゃんと整理したことがなかったので書きました。


マイグレーションとは

開発状況に応じてデータベース内にテーブルやカラム、インデックスを追加・削除をしたり、既存データに修正を加えるといったことを行う必要がある。これを楽に行えるようにしてくれるのがマイグレーション。


マイグレーションの手順

基本的には下記のステップで行う


  1. DBの構造(これをスキーマという)を変更するコード、それをRubyで記述したマイグレーションファイルを作成する。

  2. 作成したマイグレーションファイルを下記のコマンドでデータベースに適用する(migrateする)

rails db:migrate


バージョンの上げ下げ

マイグレーションは、1つのマイグレーション(ファイル)が1つのバージョンを表している。

1つのマイグレーションを追加して適用すると、データベースの構造(データベーススキーマ)のバージョンを1つあげることが出来る。

逆に、適用されているマイグレーションを取り消すと1つバージョンを下げることが出来る。


データベース変更のタイミングはいつなのか?

マイグレーションファイルを作った時点では、データベースは変更されない。マイグレーションを適用した時に初めて、マイグレーションファイルに書かれたコードが実行されて、データベースが変更される。

適用を取り消す際にも同様で、マイグレーションファイルを削除しただけではデータベースの変更は行われない。(この時は、マイグレーションを取り消すコマンドを実行する必要がある)


マイグレーションはデータベースごとの適用

どうやら、デフォルトでは開発用のデータベースに対してマイグレーションが実行される。

マイグレーションを実行するには

bin/rails db:migrate

とする。

本番環境にマイグレーションを実行したい場合、つまり本番環境のデータベースを変更したい時には

bin/rails db:migrate RAILS_ENV=production

のようにすれば問題なく本番データベースが変更される。

本や記事によっては、bin/rake を使っているものもあるが、Rails5系からbin/railsが推奨されている。


バージョンの上げ下げのコマンド

上げる場合

bin/rails db:migrate

下げる場合

bin/rails db:rollback

いくつかのマイグレーションファイルを変更したい場合(例として3つ分を取り消したい場合)

bin/rails db:rollback STEP=3

とすると3つ分戻ってくれる。


マイグレーションの名前の付け方

マイグレーションの名前はアプリケーション内で一意である必要がある。

テーブルのCreateは一度だけ行われることも多いので、あとで別カラムを追加したいと思った時にはAddPurchaseDayToItems(itemsテーブルにpurchase_dayカラムを追加する)のように具体的な名前にすると良い。

Railsは現在のデータベースの構造をdb/schema.rbに自動的に出力する。

db:schema:dump

で手動で出力することもできる。

schema(スキーマ)情報の例はこんな感じ。

ActiveRecord::Schema.define(version: 20080906171750) do

create_table "authors", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "products", force: true do |t|
t.string "name"
t.text "description"
t.datetime "created_at"
t.datetime "updated_at"
t.string. "part_number"
end
end


マイグレーションで使いそうなコマンド

bin/rails db:migrate

→最新までマイグレーションを適用する。

bin/rails db:rollback
→バージョンを1つ戻す。

bin/rails db:rollback STEP=n
→バージョンをn個分戻す。

bin/rails db:migrate VERSION=20181114051058
→指定のバージョンまでマイグレーションが適用された状態にする。

bin/rails db:migrate RAILS_ENV=test
→特定の環境下でマイグレーションを適用する。

今までなんとなくやっていたところがちゃんと理解できてよかったです。