I have two tables in my project and there are two relationships between these two tables. One of these two relationships is one-to-one and the other one is a one-to-many relationship.
My tables:
+--------------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-----------------+------+-----+---------+----------------+
| id | bigint unsigned | NO | PRI | NULL | auto_increment |
| username | varchar(255) | NO | UNI | NULL | |
| password | varchar(255) | NO | | NULL | |
| email | varchar(255) | NO | UNI | NULL | |
| common_name | varchar(255) | NO | | NULL | |
| phone_number | varchar(13) | YES | UNI | NULL | |
| role | varchar(255) | NO | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
+--------------+-----------------+------+-----+---------+----------------+
+---------------------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+-----------------+------+-----+---------+----------------+
| id | bigint unsigned | NO | PRI | NULL | auto_increment |
| unit_number | int | NO | UNI | NULL | |
| owner_id | bigint unsigned | NO | | NULL | |
| resident_id | bigint unsigned | YES | | NULL | |
| availability_status | varchar(255) | NO | | NULL | |
| number_of_rooms | int | NO | | NULL | |
| meterage | int unsigned | NO | | NULL | |
| description | text | YES | | NULL | |
| monthly_rent | int | YES | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
+---------------------+-----------------+------+-----+---------+----------------+
Relations in my models:
User model:
public function unitOwner()
{
return $this->hasMany(Unit::class, 'owner_id', 'id');
}
public function unitResident()
{
return $this->hasOne(Unit::class, 'resident_id', 'id');
}
Unit model:
public function ownerUser()
{
return $this->belongsTo(User::class, 'owner_id');
}
public function residentUser()
{
return $this->belongsTo(User::class,'resident_id');
}
I want, for example, when I delete a user, that the deleted user's ID will be deleted from the unit associated with that user (whether he is a resident of the unit or the owner of the unit). And the availability_status column of that unit, for example, can change from occupied to unoccupied.
I have a few ways in mind to implement this mode, but in all of these modes my code becomes very long. What is the shortest way to implement this?
The first thing you need to do is define a migration to set the `owner_id' to null when you delete a user:
$table->foreignId('owner_id')
->nullable()
->constrained()
->cascadeOnUpdate()
->nullOnDelete();
Then, to handle the availability_status
, you can use the model observer like this:
class UserObserver
{
public function deleted(User $user): void
{
$user->unitOwner()->update(['owner_id' => null, 'availability_status' => 'unoccupied']);
$user->unitResident()->update(['resident_id' => null, 'availability_status' => 'unoccupied']);
}
}