Laravel Eloquent ORM - 多对多删除数据透视表值

Gra*_*t J 23 orm many-to-many laravel eloquent

使用Laravel,我有以下代码

$review = Review::find(1);
$review->delete();
Run Code Online (Sandbox Code Playgroud)

Review具有与Product实体定义的多对多关系.当我删除评论时,我希望它与数据透视表中的相关产品分离,但事实并非如此.当我运行上面的代码时,我仍然看到数据透视表中的链接行.

我在这里错过了什么或者这是Laravel的工作方式吗?我知道这个detach()方法,但我认为删除一个实体也会自动将它从任何相关实体中分离出来.

Review 定义如下:

<?php
class Review extends Eloquent
{
    public function products()
    {
        return $this->belongsToMany('Product');
    }
}
Run Code Online (Sandbox Code Playgroud)

Product 定义如下:

<?php
class Product extends Eloquent
{
    public function reviews()
    {
        return $this->belongsToMany('Review');
    }
}
Run Code Online (Sandbox Code Playgroud)

提前致谢.

Mic*_*nda 49

detach方法用于从数据透视表中释放关系,而delete将删除模型记录本身,即review表中的记录.我的理解是删除不会隐含地触发分离.但是,您可以使用模型事件来触发数据透视表的清理,使用类似于:

Review::deleting(function($review)
{
    $review->product()->detach()
}
Run Code Online (Sandbox Code Playgroud)

此外,我建议这种关系是一对一的,因为一个产品会有很多评论,但一个评论不属于许多产品(通常).

class Review extends \Eloquent {
    public function product()
    {
        return $this->belongsTo('Product');
    }
}

class Product extends \Eloquent {
    public function reviews()
    {
        return $this->hasMany('Review');
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,这需要您调整数据库结构.如果您希望保留数据库结构和当前关系,则另一个选项是在数据透视表上应用外键约束,这样当删除审阅或产品时,您可以将删除级联数据透视表.

// Part of a database migration
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
$table->foreign('review_id')->references('id')->on('reviews')->onDelete('cascade');
Run Code Online (Sandbox Code Playgroud)

编辑:在添加约束时,将清理工作推送到数据库,而不必担心在代码中处理它.


Mah*_*alt 8

更简单的步骤:

在这个例子中有一个AccountTags:

要删除标签,请执行以下操作:

// delete the relationships with Tags (Pivot table) first.
$account->find($this->accountId)->tags()->detach();

// delete the record from the account table.
$account->delete($this->accountId);
Run Code Online (Sandbox Code Playgroud)

在数据透视表上确保你有- > onDelete('cascade');

$table->integer('account_id')->unsigned()->index();
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');

$table->integer('tag_id')->unsigned()->index();
$table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
Run Code Online (Sandbox Code Playgroud)


Kaz*_*sho 5

$review->product()->sync([]) 也有效。

然而$review->product()->detach()更加明确。