A New Syntax For Foreign Keys in Laravel 7
Arie Visser • May 16, 2020
laravel php databaseSince 7.x, Laravel provides a very compact syntax for creating foreign key constraints with the constrained
method.
In this post we will give a short demonstration of this syntax, and we will take a look at how the constrained
function is written in Laravel's source code.
When you want to reference a user in an orders
table, you can now write:
Schema::table('orders', function (Blueprint $table) {
$table->foreignId('user_id')->constrained();
});
Instead of:
Schema::table('orders', function (Blueprint $table) {
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
});
How does the constrained
method work?
Since the foreignId
method is just an alias for unsignedBigInteger
, the magic happens in the constrained
method.
Let's take a look at how this works.
The method can be found in Illuminate\Database\Schema\ForeignIdColumnDefinition
:
use Illuminate\Support\Str;
public function constrained($table = null)
{
return $this
->references('id')
->on($table ?: Str::plural(Str::before($this->name, '_id')));
}
When calling the constrained
method, the column in the child table will always reference to the id
column of the parent.
In the on
method, the pluralization of the characters before "_id"
results in the table name of the parent.
In the case of user_id
, this will result in users
.
When this conversion would not lead to the correct table name, it is also possible to pass another table name as argument:
Schema::table('orders', function (Blueprint $table) {
$table->foreignId('user_id')->constrained('app_users');
});
As you can see in the constrained
method, when the $table
argument is not null
, pluralization will not be applied.