【テーブル】
Booksテーブル
Categoriesテーブル
upメソッドでforeignIdが使われていたとする。
以下の記述はBooksテーブルを作成するものだ。
$table->foreignId('category_id')->constrained();であるが、これはどうやらCategoriesテーブルのidを参照するらしい。
public function up(): void
{
Schema::create('books', function (Blueprint $table) {
$table->id();
$table->string('title', 100);
$table->foreignId('category_id')->constrained();
$table->timestamps();
});
}この仕組みがよくわからなかったので調べてみた。
もくじ
foreignIdメソッドとの解説
foreignId
foreignIdメソッドは、外部キー(foreign key)を定義するために使われます。
このコードでは、category_idというカラムを作成しています。このカラムは通常、関連する別のテーブル(ここではcategories)のIDを参照します。
デフォルトでは、作成されるカラムの型は BIGINT UNSIGNED となります。
【外部キー(Foreign Key)とは?】
外部キーとは、データベースにおける”リレーション(関係)”を表現するために使われる特別なキーです。
あるテーブルの列が、”他のテーブルの主キー(Primary Key)”を参照している場合、その列を外部キーと呼びます。
constrained
constrainedメソッドは、foreignIdで作成したカラムに外部キー制約(foreign key constraint)を設定します。
このメソッドを使うと、以下を自動的に行います。
例: category_id → categoriesテーブルのidカラムを参照します。
ここから本題に入ります。
参照先として自動的に推測されること
参照先のテーブル名
$table->foreignId('category_id')->constrained();category_idのcategory部分をもとに、categoriesテーブルが推測されます。
デフォルトの動作(名前から推測)
- 推測される参照先テーブル名:
categories - 参照先カラム名:
id
->constrained()を使う場合、デフォルトの挙動として外部キーの名前(例: category_id)のプレフィックス部分(category)をもとに、参照先テーブル名が自動的に推測されます。このため、カラム名とテーブル名の命名規則が一致させるのが自然だし、便利に使える。
さらにこの仕組みを知っていればLaravelを使用している人ならば”予測ができる”という意味でわかりやすさに繋がる。
参照先のカラム名
外部キーが参照するカラム名はデフォルトでidが選ばれます。
カスタマイズ
外部キーが参照するカラムは何もしなければidが選ばれるということがわかった。
では参照するテーブルやカラムを指定することはできるのか?
→できる
参照先のテーブル名やカラム名を明示的に指定したい場合
外部キーがデフォルトのテーブル・カラムを参照しない場合は、以下のように明示的に指定できます。
$table->foreignId('category_id')->constrained('custom_table_name', 'custom_column_name');外部キーの挙動を制御(onDeleteなど)
onDeleteやonUpdateを使って外部キーの動作を制御できます。
$table->foreignId('category_id')->constrained()->onDelete('cascade');onDelete(‘cascade’)
categoriesテーブルの参照するレコードが削除された際、自動的にこのテーブルの関連レコードも削除します。
onDelete(‘restrict’)
参照先レコードが削除されるのを防ぎます。
まとめ
$table->foreignId('category_id')->constrained();ならcategory_idのプレフィックス:categoryからcategoriesテーブルを参照する。- デフォルトでIDを参照する。(カスタマイズ可能)
categoriesテーブルに関連付けられた外部キー制約を持つcategory_idカラムを作成する。
自動で外部キー制約を設定することで、参照整合性(referential integrity)を保つ仕組みをデータベースに組み込むことができる。

おつかれえええええ!!!
