Railsで外部キー成約を追加した際のIndex名のまとめ
普段 Ruby on Rails でつくられたWebサービス開発をしています。 この前、既存カラムに外部キー成約(FK)を追加したとき普段と違う命名の index名になってしました。
FK追加時にどのような index 名になるのか気になったので、いろいろなパターンを試してまとめました!
Indexの貼り方
RailsアプリケーションではFKを貼る際に大きく以下の方法があります。
1. テーブル作成時に指定するカラム作成時にFKを貼る
class AddTable < ActiveRecord::Migration[5.2] def change create_table :parent1s create_table :parent2s create_table :parent3s create_table :children do |t| t.references :parent1, foreign_key: true end end end
2.カラム追加時にFKを貼る
class AddChild < ActiveRecord::Migration[5.2] def change add_reference :children, :parent2, foreign_key: true end end
3.後からFKを貼る
class AddFk < ActiveRecord::Migration[5.2] def change add_column :children, :parent3_id, :bigint add_foreign_key :children, :parent3s, column: "parent3_id" end end
生成されたIndex
実行結果
schema.rb
ActiveRecord::Schema.define(version: 2019_08_10_050953) do create_table "children", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| t.bigint "parent1_id" t.bigint "parent2_id" t.bigint "parent3_id" t.index ["parent1_id"], name: "index_children_on_parent1_id" t.index ["parent2_id"], name: "index_children_on_parent2_id" t.index ["parent3_id"], name: "fk_rails_c04e2dbc44" end create_table "parent1s", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| end create_table "parent2s", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| end create_table "parent3s", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| end add_foreign_key "children", "parent1s" add_foreign_key "children", "parent2s" add_foreign_key "children", "parent3s" end
add_foreigin_key
でFKを貼った場合、Indexの名前がFK成約と同じ名前になってしまいます。 fk_rails_c04e2dbc44
Indexは後からチューニングする際に名前の規約が決まっていた方が便利なので、この名前は使いたくないですよね。 対処方法は、以下のように際にIndexを貼り、あとでFKを貼ることで回避することができます
class AddFk < ActiveRecord::Migration[5.2] def change add_column :children, :parent3_id, :bigint add_index :children, :parent3_id add_foreign_key :children, :parent3s, column: "parent3_id" end end
まとめ
- FKの貼り方は大きく3種類ある
- 既存カラムに
add_foreign_key
でFKを追加したときだけ Indexの名前が違うので注意する