Foreign Id to same table in Laravel migrations
April 29, 2022 ‐ 2 min read
Creating foreign Id's in Laravel abstracts away quite a lot if you adhere to the naming conventions. That is; when you're about to add a foreign Id called user_id
, Laravel assumes from the Id name you want to reference the id
from the users
table.
Setting up such a relation to the same table is an option too, but it requires you to overwrite this default behavior. See the following, where a foreign Id is created called parent_id
. If we would Laravel try to figure out which table this should reference then it would try to create a foreign key constrained to a table called parents
.
<?php
...
$table->foreignId('parent_id')->constrained()->onDelete('cascade');
...
Instead, you want to specify the table name your are referencing as the first argument to the constrained()
method:
<?php
...
$table->foreignId('parent_id')->constrained('pages')->onDelete('cascade');
...
Such a pattern is useful when you have models that have somewhat of a recursive structure; a directory model that has a parent directory for example.
See for a full migration the example below:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('pages', function (Blueprint $table) {
$table->id();
$table->foreignId('parent_id')->constrained('pages')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('pages');
}
};