67964
rails で Active Record すなわちデータベースを取り扱うと、 MigrationFile
の作成・適用を行うことになります。これは、なんとなく、「新しい(未適用)の Migration File があれば、それを file name の
alphabetical order 順 (そして、 file name は先頭が datetime 的 prefix
である必要があるので、ほぼほぼ作成順)」で適用してくれるツールだと理解しています。

ここで疑問になるのが、このふるまいはどうやって実現されているのか、ということです。

  1. 一度適用した MigrationFile を削除した(してしまった場合)
  2. db:setup の際に schema.rb の元になったデータベースの構築に使われていない MigrationFile が db/migrations にまぎれこんでいた場合

などのエッジケースにおいて、 rails の migration がどうふるまうのかが、ふと、自分は良く理解していないな、と思うにいたりました。

# 質問

  * 疑似コードぐらいの粒度では、rails の `db:migrate`, `db:reset`, `db:setup`, `db:migrate:reset` は、それぞれどのようにふるまっていますか?
  * その挙動がまとまっている資料はありますか?
CC BY-SA 4.0
2020-06-24T03:44:46.600
67940
2020-06-24T17:37:39.283
2020-06-24T06:28:12.400
3060
754
question
ruby-on-rails
rails の migration の仕様について
データベースに schema_migration というテーブルが造られて  
成功したマイグレーションファイルの数字の部分(YYYYMMDDHHMMSS)が記憶されていて  
db/migrate ディレクトリと比較して未実行のマイグレーションを検出してます

なので

  1. 一度適用した MigrationFile を削除した(してしまった場合)  
何も起きません  
DB側にのみ履歴が存在しますが特にエラーにもなりません

  2. データベースの構築に使われていない MigrationFile が db/migrations にまぎれこんでいた場合  
履歴にないので当然実行されます

> db:migrate, db:reset, db:setup, db:migrate:reset は、それぞれどのようにふるまっていますか?

その前に schema.rb というのがあってはマイグレーションが成功したときに更新されます  
最後に成功したスキーマダンプファイルのようなものですね

**db:migrate**  
DB の状態を正として未実行のマイグレーションファイルだけを適用します  
すでに適用済みのマイグレーションファイルを変更していても反映されません

**db:migrate:reset**  
マイグレーションを正として  
すべてのテーブルをドロップしてマイグレーションをすべて再実行します

この２つはマイグレーションファイルのみを見ていて schema.rb はみません（更新はします）

**db:reset**  
schema.rb を正として  
すべてのテーブルをドロップして schema.rb の状態にテーブルを再作成します

**db:setup**  
最初にしか使ったことがなくて自信がないんですが  
データベース作成スキーマ変更シードデータ投入だけ行うんだと思います  
既にDBが作成されてる場合エラーで止まるのかスキーマ更新をやるのかわからないですが

この２つはマイグレーションは見ずに schema.rb だけを参照します

基本的にどこか１つの環境にでも実行したマイグレーションファイルは変更してはいけない  
スキーマを変更したいときは修正マイグレーションを作る  
という運用さえ守ってれば初回 setup とあと db:migrate だけでおかしなことはおきないはずです

* * *

<https://qiita.com/kenkentarou/items/9d2dd0d032f530311d2a>  
こちらによると  
db:migrate:reset = db:drop + db:migrate  
db:reset = db:drop + db:setup  
db:setup = db:create + db:schema:load + db:seed  
ということみたいです

<https://qiita.com/katsuyan/items/59afccf9d0def886e8b3>  
db:schema:load は force:true をつけると drop and create  
つけなければ create だけですでに存在する場合は already exist エラーになるようです

なのでやはり db:migrate 以外でスキーマ変更をすると  
テーブル再作成になってレコードも消えるので注意
CC BY-SA 4.0
2020-06-24T17:08:25.940
67964
2020-06-24T17:37:39.283
2020-06-24T17:37:39.283
67940
answer