Reputation: 2418
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)
Upvotes: 0
Views: 1367
Reputation: 15786
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.
Upvotes: 1
Reputation: 408
If you want to delete a child from a relationship without deleting the whole relationship you have to set the Foreing Key column in the parent table as nullable and to set it to null when the child is deleted. You can do this in the Laravel migrations like this:
Schema::create('parents', function (Blueprint $table) {
$table->id();
$table->foreignId('child_id')->nullable()->constrained('childs')->onDelete('set null');
$table->string('name');
});
Upvotes: 1