I have a parent child relation in users.
I want to delete a child. But before that, I need to remove all references from the parents to the child.
I was expecting this to work - but is not:
$child->superiorUsers()->detach($child->id);
$child->delete();
The superiorUsers() looks like this:
public function superiorUsers() { return $this->belongsToMany( 'App\Models\User', 'user_user', 'user_id', 'superior_id' ); }
Any idea what I am doing wrong please?
Edit: I am writing unitTests to delete the user and I am getting the error that the relation is still there.
SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (
user_user
, CONSTRAINTuser_user_user_id_foreign
FOREIGN KEY (user_id
) REFERENCESusers
(id
)) (SQL: delete fromusers
whereid
= xxx)
Create a new migration to alter the foreign key constraint
Schema::table('user_user', function (Blueprint $table) {
$table->dropForeign(['user_id']);
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
This will mean that if a user is deleted, any records on user_user with the deleted user_id will be deleted as well.
Another option is onDelete('set null')
so the field is only changed to be null.
Another option is to use the User's deleting
event.
# User model
protected static function booted()
{
static::deleting(function ($user) {
$user->superiorUsers()->sync([]);
$user->inferiorUsers()->sync([]);
});
}
public function superiorUsers()
{
return $this->belongsToMany(
'App\Models\User',
'user_user',
'user_id',
'superior_id'
);
}
public function inferiorUsers()
{
return $this->belongsToMany(
'App\Models\User',
'user_user',
'superior_id',
'user_id'
);
}
But in my opinion, if you're not using soft deletes this kind of logic is better left to the database.