如何在删除 child 之前从 child 分离 parents? (Laravel Eloquent)

How to detach parents from child before deleting the child? (Laravel Eloquent)

我在用户中有 parent child 关系。

我想删除一个child。 但在此之前,我需要删除 parent 对 child.

的所有引用

我原以为这会起作用 - 但不是:

$child->superiorUsers()->detach($child->id);

$child->delete();

superiorUsers() 看起来像这样:

public function superiorUsers()
{
    return $this->belongsToMany(
        'App\Models\User',
        'user_user',
        'user_id',
        'superior_id'
    );
}

知道我做错了什么吗?

编辑: 我正在编写 unitTests 来删除用户,但我得到的错误是关系仍然存在。

SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (user_user, CONSTRAINT user_user_user_id_foreign FOREIGN KEY (user_id) REFERENCES users (id)) (SQL: delete from users where id = xxx)

创建新迁移以更改外键约束

Schema::table('user_user', function (Blueprint $table) {
    $table->dropForeign(['user_id']);
    $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});

这意味着,如果删除了用户,user_user 上包含已删除 user_id 的任何记录也将被删除。

另一种选择是onDelete('set null'),因此该字段仅更改为空。


另一种选择是使用用户的 deleting 事件。

# 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'
    );
}

但在我看来,如果您不使用软删除,这种逻辑最好留给数据库。

如果要从关系中删除子项而不删除整个关系,则必须将父项 table 中的 Foreing Key 列设置为可为空,并在删除子项时将其设置为空。您可以在 Laravel 迁移中执行此操作,如下所示:

Schema::create('parents', function (Blueprint $table) {
        $table->id();
        $table->foreignId('child_id')->nullable()->constrained('childs')->onDelete('set null');
        $table->string('name');
    });