##マイグレーションの仕組みと流れ
マイグレーションを行う際に、3つのファイルが実行される。
■マイグレーションファイル
データベースに対して行いたい変更を記述するもの
■スキーマファイル(schema.rb
)
現状のデータベースの状態を保存するもの
■データベース
◆流れ
1. マイグレーションファイルに変更内容を書く
2. マイグレーションを実行(db:migrate
)することで、データベースの内容が変更される
3. 変更された内容のデータベースの状態で、schema.rb
が更新される
4. schema.rb
のタイムスタンプが更新される
##マイグレーションファイル作成
■新規でモデルから作成し、マイグレーションファイルも作成する場合。
rails g model モデル名 追加するカラム名:型(カラムは後でも書けるのでどちらでも)
#例
rails g model user name:string age:integer
ここでrails db:migrate
を行うと、マイグレーションファイルが生成される。
(今回はname:string age:integer
無しのモデルに何も編集していない状態で進める。)
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.timestamps
end
end
end
カラムを無しで作成するとt.timestamps
のみがデフォルトで記載されている。
それにより、作成日時を意味するcreated_at
と、更新日時を意味するupdated_at
がカラムに追加される。
■モデルは既にあって、カラムを追加したいからマイグレーションファイルだけ作成する場合。
rails g migration Add 追加するカラム名 To 追加するテーブル名 追加するカラム名:型(カラムは後でも書けるのでどちらでも)
#例
rails g migration AddEmailToUsers email:string
あとはバリデーションを追記するなりしてrails db:migrate
をすればカラムが追加される。ただし追加だけでなく既にあるファイルを変更となると、ファイルのステータスから見ないといけない。
##マイグレーションファイルのステータス
マイグレーションファイルにはステータスが存在する。
ステータスはrails db:migrate:status
コマンドで確認できる。
$ rails db:migrate:status
Status Migration ID Migration Name
--------------------------------------------------
up 20190501111550 Create blogs
up 20190501123505 Change blogs title not null
down 20190501123715 Change blogs content not null
down 20190502033857 Create comments
このステータス画面では、どのマイグレーションファイルが実行中で、どのファイルが実行されていないかが分かる。
up
が実行中で、down
が実行されていない状態である。
マイグレーションを実行(db:migrate
)することで、up状態
になる。
このマイグレーションファイルのup/down
の状態が重要になってくる。
例えば、マイグレーションファイルの変更を行いたいときなどにステータスの有無が必要になってくる。
##マイグレーションファイルの変更を行う場合
仮にuserテーブル
にカラムを追加・変更を実施する際に、マイグレーションファイルのステータスを**down
**にしなければならない。
up状態
で、マイグレーションファイルに変更を加えて、rails db:migrate
を実施しても全く反映されない。(装備中の防具を外さないと新しい装備が付けれない的な)
down状態
にするには、コマンドでrails db:rollback
を実行すればできる。変更を施した後、またrails db:migrate
を行えばup状態
になる。
⚠️注意
マイグレーションファイルは基本的に上から(時間順)に実行されていく。rollback
は反対の下から(最新時間順)から1個のファイルのみdown
になるので、変更したいファイルまで飛ばしたい場合にはSTEP数を指定してロールバックする。もしくはMigration ID
を指定して行う。
#STEP数を指定してロールバック
$ rails db:rollback STEP=ステップ数
#Migration IDを指定してロールバック。IDはステータスで確認できる。
$ rails db:migrate:down VERSION=oooooooooo
##up状態のマイグレーションのファイルを削除すると「NO FILE」ができる
もし不要なマイグレーションファイルがあって削除する場合、down状態
で削除したらいいが、up状態
のまま消してしまうと以下のようになる。
Status Migration ID Migration Name
--------------------------------------------------
up 20190915023701 Create posts
up 20190915065320 ********** NO FILE **********
down 20190915080932 Devise create users
このNO FILE
を削除する方法として、ダミーファイルを作成し、そのファイルを削除することで解決する。
Migration ID
をコピーしてダミーファイルを作成。(名前は適当でOK)
touch db/migrate/20190915065320_hoge.rb
ダミーファイルが作成できたら、ちゃんとNO FILE
だったところに割り当てられているか確認する。
Status Migration ID Migration Name
--------------------------------------------------
up 20190915023701 Create posts
up 20190915065320 Hoge
down 20190915080932 Devise create users
確認できたら、このダミーファイルをdown状態
にし、削除すれば良い。
$ rails db:migrate:down VERSION=20190915065320
$ rm db/migrate/db/migrate/20190915065320_hoge.rb
##コマンド集
マイグレーション関連コマンド集
コマンド | 意味・機能 |
---|---|
rails g migration クラス名 | マイグレーションファイル作成 |
rails g model モデル名 | モデル作成 |
rails db:migrate | マイグレーション実行 |
rails db:migrate:status | ステータス確認 |
rails db:rollback | ロールバック |
rails db:rollback STEP=ステップ数 | STEP数を指定してロールバック |
rails db:reset | 全てのDBを削除した後に、schema.rbを元にDB作成 |
rails db:migrate:reset | 全てのDBを削除した後に、db/migrate/**.rb を元に古い順から実行 |
##参考記事
Ruby on Rails 『NO FILEのmigrationを削除する方法』
[Rails]マイグレーションファイルについて勉強してみた!(テーブルへのカラム追加)
Rails:マイグレーションファイル、スキーマファイル におけるタイムスタンプの役割
rails generate migrationコマンドまとめ
rails db:migrate:resetできなかったのでrails db:resetした