Railsで新規のテーブルを作成したり、カラムを追加したりするときには、マイグレーションを作成しますが、マイグレーションについてはついつい忘れがちなので、今回は外部キー制約の貼り方についてまとめてみました。
ちなみに外部キー制約とは
外部キー制約とは、テーブルの指定したカラムに格納できる値を他のテーブルに格納されている値だけに限定するものです。
ということらしいです。
※環境
Rails 5.2.1
Ruby 2.5.0
DB sqlite
references
references
はインデックスは貼ってくれるが、外部キー制約にはならないようです。
db/migrate/20181029160103_create_children.rb
class CreateChildren < ActiveRecord::Migration[5.2]
def change
create_table :children do |t|
t.references :parent
t.timestamps
end
end
end
CREATE TABLE IF NOT EXISTS "children" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "parent_id" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL);
CREATE INDEX "index_children_on_report_id" ON "children" ("parent_id");
index:true
index: trueを加えてもSQL自体に変化はないらしい。
db/migrate/20181029162344_create_children.rb
class CreateChildren < ActiveRecord::Migration[5.2]
def change
create_table :children do |t|
t.references :parent, index: true
t.timestamps
end
end
end
CREATE TABLE IF NOT EXISTS "children" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "parent_id" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL);
CREATE INDEX "index_children_on_parent_id" ON "children" ("parent_id");
foreign_key: true
これでようやく外部キー制約がつきます
CONSTRAINT オプションでForeign keyに名前がつけられます
db/migrate/20181029162344_create_children.rb
class CreateChildren < ActiveRecord::Migration[5.2]
def change
create_table :children do |t|
t.references :parent, foreign_key: true
t.timestamps
end
end
end
CREATE TABLE IF NOT EXISTS "children" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "parent_id" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL, CONSTRAINT "fk_rails_554cba9b33"
FOREIGN KEY ("parent_id")
REFERENCES "parents" ("id")
);
CREATE INDEX "index_children_on_parent_id" ON "children" ("parent_id");