【问题标题】:How to detach parents from child before deleting the child? (Laravel Eloquent)如何在删除孩子之前将父母与孩子分离? (Laravel 雄辩)
【发布时间】:2021-08-08 10:29:39
【问题描述】:

我在用户中有父子关系。

我想删除一个孩子。 但在此之前,我需要删除父母对孩子的所有引用。

我原以为这会起作用 - 但事实并非如此:

$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]:完整性 违反约束:1451 无法删除或更新父行:a 外键约束失败 (user_user, CONSTRAINT user_user_user_id_foreign 外键 (user_id) 引用 users (id)) (SQL: 从users 中删除id = xxx)

【问题讨论】:

  • “它不起作用”是什么意思?
  • 我正在编写用于删除用户的 uniTests,当我删除用户时,我收到关系仍然存在的错误。我会更新问题谢谢
  • 您需要更改 user_user 迁移,以便将onDelete('cascade')onDelete('set null') 添加到约束或使用雄辩的deleting 事件。
  • 你是多对多关系,所以不能删除孩子。

标签: php laravel eloquent eloquent-relationship


【解决方案1】:

创建一个新的迁移来改变外键约束

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

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

【讨论】:

  • 谢谢,迁移更新成功了。知道为什么 $child->superiorUsers()->detach($child->id);不会做同样的事情吗?
  • 因为它不会像你想象的那样做。它只删除 user_user 行,其中 $child 既是 superior_id 又是 user_id
【解决方案2】:

如果要从关系中删除子关系而不删除整个关系,则必须将父表中的 Foreing Key 列设置为可为空,并在删除子关系时将其设置为 null。你可以在 Laravel 迁移中这样做:

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

【讨论】:

    猜你喜欢
    • 2019-06-24
    • 1970-01-01
    • 2012-09-12
    • 2019-02-02
    • 2018-03-29
    • 2010-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多