decochのブログ

フリーランスのiOSエンジニア decoch のブログです

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の名前が違うので注意する