Eloquent: Relationships - Laravel 12.x - The PHP Framework For Web Artisans
In order to create a one to one relationship between 2 tables, a foreignId
column needs to be added to the table which holds the many side of the relationship.
<aside> 💡
The foreignId
method creates an UNSIGNED BIGINT
equivalent column
</aside>
<aside> 💡
The constrained
method will use conventions to determine the table and column being referenced.
constrained
uses the string given to foreignId
which by convention should be [name-of-the-table]-[name-of-the-column]
.
If conventions aren’t respected, constraint should be explicitly created:
$table->foreignId('user_id')->constrained(
table: 'users', indexName: 'posts_user_id'
);
</aside>
<?php
use Illuminate\\Database\\Migrations\\Migration;
use Illuminate\\Database\\Schema\\Blueprint;
use Illuminate\\Support\\Facades\\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('phones', function (Blueprint $table) {
$table->id();
$table->string(column: 'number');
**$table->foreignId('user_id')->constrained();**
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('phones');
}
};
<aside> 💡
In a one to one relationships, a belongsTo
method should be implemented in the child model which signifies the model belongs to a single instance of another model.
</aside>
<?php
namespace App\\Models;
use Illuminate\\Database\\Eloquent\\Model;
use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;
class Phone extends Model
{
protected $fillable = ['number','user_id'];
public function user(): **BelongsTo**
{
**return $this->belongsTo(User::class);**
}
}
<aside> 💡
In a one to one relationships, a hasOne
method should be implemented in the parent model which signifies the model owning exactly one of the related model.
</aside>
<?php
namespace App\\Models;
use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;
use Illuminate\\Foundation\\Auth\\User as Authenticatable;
use Illuminate\\Notifications\\Notifiable;
use Illuminate\\Database\\Eloquent\\Relations\\HasOne;
class User extends Authenticatable
{
protected $fillable = [
'name',
'email',
'password',
];
public function phone(): **HasOne**
{
**return $this->hasOne(Phone::class);**
}
}
<aside> ⚠️
In order to use load()
and with()
methods in a query, the relations should be already defined on the model that the query starts with
</aside>
<aside> 💡
Eager loading retrieves the relationship data at the same time as the primary data in a single query by joining the tables.
$users = User::with('phones')->get(); // all() won't work here !
</aside>
<aside> 💡
Lazy loading retrieves the relationship data only when it is accessed. It can lead to multiple database queries.
$users = User::all();
foreach ($users as $user) {
$phone = $user->phone;
}
Using load()
method:
$users::all()->load('phone');
</aside>