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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27330551/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 16:49:29  来源:igfitidea点击:

Laravel Eloquent ORM - Many to Many Delete Pivot Table Values left over

laravelormmany-to-manyeloquent

提问by Grant J

Using Laravel, I have the following code

使用 Laravel,我有以下代码

$review = Review::find(1);
$review->delete();

Reviewhas a many to many relationship defined with a Productentity. When I delete a review, I'd expect it to be detached from the associated products in the pivot table, but this isn't the case. When I run the code above, I still see the linking row in the pivot table.

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

Have I missed something out here or is this the way Laravel works? I'm aware of the detach()method, but I thought that deleting an entity would also detach it from any related entities automatically.

我在这里遗漏了什么还是这就是 Laravel 的工作方式?我知道该detach()方法,但我认为删除实体也会自动将其与任何相关实体分离。

Reviewis defined like this:

Review定义如下:

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

Productis defined like this:

Product定义如下:

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

Thanks in advance.

提前致谢。

回答by Michael Dyrynda

The detach method is used to release a relationship from the pivot table, whilst delete will delete the model record itself i.e. the record in the reviews table. My understanding is that delete won't trigger the detach implicitly. You can use model eventsto trigger a cleanup of the pivot table, though, using something like:

分离方法用于从数据透视表中释放关系,而删除将删除模型记录本身,即评论表中的记录。我的理解是删除不会隐式触发分离。不过,您可以使用模型事件来触发数据透视表的清理,使用以下内容:

Review::deleting(function($review)
{
    $review->product()->detach()
}

Also, I would suggest that the relationship would be a one to many, as one product would have many reviews, but one review wouldn't belong to many products (usually).

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

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

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

Of course, this would then require that you tweak your database structure. If you wanted to leave the database structure and your current relationships as they are, the other option would be to apply a foreign key constraint on the pivot table, such that when either a review or product is removed, you could cascade the delete on the pivot table.

当然,这需要您调整数据库结构。如果您想保留数据库结构和您当前的关系,另一种选择是在数据透视表上应用外键约束,这样当评论或产品被删除时,您可以级联删除数据透视表。

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

Edit: In adding the constraint, you push the cleanup work onto the database, and don't have to worry about handling it in code.

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

回答by Mahmoud Zalt

Simpler Steps:

更简单的步骤:

In this example an Accounthas many Tags:

在这个例子中,Account有很多Tags

To delete the Tags, then the Account do this:

要删除标签,则帐户执行以下操作:

// 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);

On the Pivot Table make sure you have ->onDelete('cascade');

在数据透视表上确保您有->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');

回答by Kazuya Gosho

$review->product()->sync([])also works.

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

However $review->product()->detach()is much more explicit.

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

回答by Hamza Kouadri

i guess you have a error in your models relationship conception, the product has many reviews but the review associated with one product so you have here one to many relationship. but in general the answer in the general case will be using:

我猜你的模型关系概念有误,产品有很多评论,但评论与一种产品相关,所以你在这里有一对多的关系。但总的来说,一般情况下的答案将使用:

$product->reviews()->sync([]);