Ruby
Rails
Ridgepole

Ridgepole テーブル定義をsplitオプション付きでエクスポートする際の落とし穴

はじめに

先日弊社ではRidgepoleを導入したのですが、
Rails マイグレーションの廃止とRidgepoleの導入・利用方法
思わぬところに落とし穴が存在し他ので共有します。

出力コマンド

テーブル定義をSchemafileに出力

これでSchemafileに現在の全テーブル定義がエクスポートされます。

bundle exec ridgepole -c config/database.yml -E development --export -o db/Schemafile

テーブル定義をテーブルごとにファイル分けして出力

テーブルごとにファイル分けする場合にはsplitオプションをつけます。

bundle exec ridgepole -c config/database.yml -E development --split --export -o db/Schemafile

消えたFK (外部キー)の定義の行方は...

テーブル定義をテーブルごとにファイル分けして出力した場合、FKの定義が失踪します。

create_table "users", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
  t.string "email", default: "", null: false
  t.string "username", default: "", null: false
  t.bigint "team_id"
  t.datetime "created_at", default: -> { "CURRENT_TIMESTAMP" }, null: false
  t.timestamp "updated_at", default: -> { "CURRENT_TIMESTAMP" }, null: false
  t.index ["team_id"], name: "index_users_on_team_id"
end

# add_foreign_key "users", "teams" <- こいつが行方不明

不要な外部キーを削除したくてもapplyでエラーが出るからどこかに存在していることは間違いない!

FK (外部キー)の定義の行方と原因

失踪したわけではないのです。ちゃんと存在しています。

結論から言うと、

アルファベット順で一番最後になるファイルにがっつりまとめて書かれています。

create_table "values", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
  t.string "name"
  t.datetime "created_at", default: -> { "CURRENT_TIMESTAMP" }, null: false
  t.timestamp "updated_at", default: -> { "CURRENT_TIMESTAMP" }, null: false
end

# 全定義ここにある
add_foreign_key "users", "teams"
add_foreign_key "japan", "tokyo"
add_foreign_key "tokyo", "shibuya"
.....

おそらく/db/schema.rbの生成と同じロジックを使っているためだと思われます。

これに気づかないと詰みますよね...

ブログ記事で見たい方はこちら → Ridgepole テーブル定義をsplitオプション付きでエクスポートする際の落とし穴