はじめに
これはフィヨルドブートキャンプ Advent Calendar 2025 | Fjord Calendarの13日目の記事です。
昨日 12月12日は、 zamamiさんのCORSをちゃんと理解するでした。
CORSぜんぜん知らん??!!となってしまったのですが、Rails APIを別フロントで叩くみたいな感じだと意識する必要があるんですね👀
大変勉強になりました🙏
チーム開発で苦労したgit、Rails、DB
今回は「チーム開発前にもっと理解しておきたかった、gitとRailsとDBあたりの関係性」をふわっと自分なりに説明してしようと思います。
※注意 1今回は「分かりやすく」を優先するので、厳密な定義や規格には沿わない表現を多々します。
※注意2 想定知識はFBCのデータベースプラクティスまでです。でも前段階でも読めるように頑張って書きます
大前提の知識 git
gitはコードの差分をバージョン管理してくれるシステムです。
コミットと呼ばれる単位ごとに保存します。セーブポイントみたいなものです。
ブランチという機能があり*変更内容を分岐させて記録させることができます。
名前のごとく、枝分かれっぽいイメージ、あるいは、SFの並行世界みたいな。
ブランチは変更目的ごとに分岐させ、その目的に沿った変更のみ行います。
(例)ロボットを作ろうリポジトリ
頭を作るブランチ、胴体作るブランチ、右手作るブランチ…
DBは異世界
DBはRailsアプリにおける様々なデータを保存してくれる優秀な保管庫です。
しかし、DBはRailsにとって異世界です。
それぞれの世界の言葉が根本的に異なると思っていたらよいかなと思います。
異世界なので基本的にgitで管理することができません
git管理できないので、開発環境ではローカルPCに保存されている、ひとつのDB世界を全ブランチで共有することになります。
それはDBの種類がPostgreSQLだろうがSQLiteだろうがMySQLだろうが変わりません。

異世界語(SQL)と翻訳機能
DBという名の異世界で色々行うにはその世界の言葉が必要となります。これがSQLと呼ばれるものです。
ただ、SQLを毎回使うのは大変なので、Railsには翻訳機能があります。
SQLをわざわざプログラマが打たなくても、こちらのやりたいことをDBによしなに伝えてくれます。
「データ取得」「データ追加・削除」などのデータの読み書きについては、基本的にCRUDメソッドと呼ばれるものを使います。
「テーブル作成・削除」「カラム追加・削除」「NULL制約」「index」等々のデータをどう保存しておくかのルールや、枠組みそのものを変更する場合は、基本的にmigrationファイルを使います。

migrationファイルとschema.rb
migrationファイルは発注書みたいなものです。
「これこれ、こういう変更をDBにしたいです」ということを書いておくと、RailsがDBにうまく伝えてくれます。
SQLにはDBごとに方言があると言われておりますが、そのへんもうまく伝えてくれます。
rails db:migrateを行うと発注書(migrationファイル)をもとに、Railsが翻訳してDBに伝えてくれて発注内容に沿って変更されます。
そして、変更されたDBの全体の内容をschema.rbに書き写してくれます。
schema.rbは領収書のようなものです。
schema.rbとローカルDBとの食い違い
今までの内容、それぞれ単体だとそんな難しい話じゃないと思います。
ただ、git管理とDBの仕様が絡むと、少しだけややこしい状態になります
migrationファイルとschema.rbはgit管理の対象です。
しかし、DBファイルはgit管理対象外です。そして、内容は全てのブランチで共有されています。
そのため、あるブランチAでDBに変更を加えたあと、別ブランチBに移動すると、DBの実内容と、ブランチBのmigartionファイル・schema.rbとの食い違いが起こるようになります。
rails db:migrate:statusコマンドはDBの実内容を問い合わせて、マイグレーションの実行状況を確認してくれます。
(例)Create postsまでは全てのブランチで把握していることとする。
ブランチAで何らかのmigrationファイルを作成し、db:migrateしたあと、ブランチBに移動してrails db:migrate:statusしたとする。
Status Migration ID Migration Name -------------------------------------------------- up 20251210xxx Create posts # ここまではBでも把握している up 20251211xxx *** NO FILE *** # 20251211xxxIDのファイルはAにしかない
※発注番号であるMigration IDを保存するテーブルがDBにはあるので、BブランチにファイルがなくともMigration IDはstatusで表示できる。
でもファイルがないので、BブランチではMigration Nameがわからず、「なにそれ、知らん…」となっている。
食い違いをどうしたらよい?
「えええ、どうしたらいいんだ〜!??」となりますが、一度深呼吸します。
ここでは、「migrationファイル、schema、DBそれぞれの役割」を思い出すと、自ずとどうすればいいかが朧げにわかってきます。
まず、DBですがアプリの肝となるあらゆる情報を保存しておく保管庫だったかと思います。
ところで、開発環境で動かしているDBは、「ローカル環境」というやつで、本番データが一つも入っていない開発用・練習用のDBです。
なので、保存されているデータ自体はそこまで重要ではないです。
(逆にいうと本番環境ではそのデータが超超超超超大事です。)
少なくとも、「FBCのプラクティスでは」という枕詞付ではありますが、
ローカルDBは開発でアプリを試す上で必要なのであって、何がなんでも保持しなければならないわけではなく、resetして作り直してもいいくらいです。*1
重要なのはそのブランチの目的は何で、どのような変更がなされたか。それをgitで記録することです。
*1 後述する伊藤さんの記事によると、ローカルDBのデータ保持が必要な実務もあるので、「学習の一環として、プラクティス上ではresetをやってみる」くらいに考えると良さそうです。
プラクティスやチーム開発では、seedデータという初期データがあるので、初期データを投入すればまっさらなDBになります。
ローカルDBを気軽にresetしてもいいかどうかは人によって色々持論があるようです。
ブランチにおいて、本当に必要な記録を残す
migrationファイル、schemaは発注書と領収書だったかと思います。
ブランチでは目的に沿った変更内容のみ記録します。
よって、発注書と、結果内容である領収書を正確な状態で残すことが役割です。
これらはgit管理されるものなので、実際のローカルDBがなんであるかはさておいて、そのブランチ上で整合性が取れていればそれでOKです。
Userモデルを作るブランチに「userテーブルを作る発注書と領収書記録」があるのはいいですが、「postテーブルを作る発注書と領収書記録」があるのはNGということです。
先人の知恵から学ぶ
「食い違いが起こったらどうしたらよいか?」の具体的な方法ですが、以下のように素晴らしい記事があります。
メンターの伊藤さんが丁寧で正確な記事を書かれています。 qiita.com
また、卒業生のかずのこさんが対処方法の記事をアップされています。 ama-tech.hatenablog.com
慣れが必要だと感じる
チーム開発当時、DBがブランチ共有であること等がいまいちわかっておらず、大変混乱しました。
ひとえに、「git管理」と「DB」がそれぞれ別々の理で動いているということが原因であり、それを理解するまでにめちゃくちゃ時間がかかりました。
「gitだけでもややこしくてようやく慣れたのに、DBは別の法則で動いているんか??」と当時思いました。
DB関係は色々気をつけないといけないことがたくさんありますが、「何故気をつけないといけない?」の理由は「端的にいうと異世界だから」だと個人的には思っております(笑)
あえてDBをぶっ壊す
先日、Railsガイドを数人の受講生と一緒に読みこんでいる際、あえて禁忌とされている動きを色々してみて、DBをぶっ壊す。そして色々調べてみるということをやってみました。
具体的にいうと以下のような感じのことをしました。
- 変更してからブランチ移動
- マイグレーションした後のmigrationファイルをがっつり変更してみる
- 変更したあとに、downしてみる
- migrationファイルの名前を変更する
- migrationファイルのIDを変更する
- DBをコンソールから直接開き、DBのmigrationファイル記録テーブルを改ざん
当たり前ですが、整合性が取れなくて色々ぶっ壊れたのですが、練習リポジトリだったので痛くも痒くもありません。
色々コマンドを試したりもしました。
migrationファイル・schema.rbはどのタイミングで記録されるのか、resetコマンドも色々種類があるが違いは何か、等々、勉強になることがたくさんありました。
DBってよく分からない・怖いな…と思っている私のような人にこそ、このDBぶっ壊し練習は強くおすすめします。
明日の記事
明日のアドベントカレンダーはunikounioさん、hirokiejさんです✨