「私が貼ったインデックス、全部消されているのですが...」
今週仕事をしていたら、このような連絡をいただいた。
あれ、schema.rbは手修正してはいけないんじゃなかった?(違う)
経緯
いつものようにマイグレーション込みのPRを作成し、レビュー後マージされその週の本番リリースまでにその内容がSTGところだった。
コンフリクトも生じていなく、developマージの時はschema.rbのバージョンだけ新しくしてapprove、マージ。
しかし、マイグレーションの時にインデックスを貼るところの記述がschema.rbから丸ごと消えていてそのままSTGが運用されていた。
兆候
確かに最近マイグレーションを実行するたびにすごい量のモデルアノテーションの変更分が出ていた。
うざいなと思いつつ、原因を探ろうとはしなかった。
原因
マイグレーション実行順序
以下のような状況を考える。
develop branch: A -> B -> C
\
feature branch: D -> E
今回私はAからブランチを切っていた。
その間に他の人がCの変更(インデックスを貼る)をdevelopに入れた。
その時、Cには変わったschema.rbが入っている状態になる。
ここで、Dにdevelopをpullし、マイグレーションを走らせた。
その時、schema.rbに変更が出てしまっていたのに、私はそれをそのままcommitしてしまった。
developをpullするタイミングでコンフリクトが起きると思っていたが、実際にはgitのauto mergeが働いてしまう時があるという。。
正しいフロー
dumpし、schema:loadする
上記の「兆候」のような現象が起きていると、develop(もしくはmain)のschema.rbをもとにschema:loadをして順番に合った正しいマイグレーションを走らせた状態にする必要がある。
しかし、schema:loadは今までのデータを飛ばしてしまうため、その前に今のデータをdumpする必要がある。
そのdumpの処理がめんどくさいから、社内にはやっている人はいなさそうな感じだった。
今回私はdockerのボリュームを消して、ビルドをし直すことで解決した。(めんどくさい)
どっちにせよデータは消えるので、結果的にはschema:loadだけでよかった。
おわりに
なんにせよ、自分で行なっていないものをcommitすることは危険。
マイグレーションで出てくるschema.rbは絶対ではない。
知ってたら当たり前なことを、今回の失敗経験で学んだ。