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
Laravel Eloquent ORM - Many to Many Delete Pivot Table Values left over
提问by Grant J
Using Laravel, I have the following code
使用 Laravel,我有以下代码
$review = Review::find(1);
$review->delete();
Review
has a many to many relationship defined with a Product
entity. 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()
方法,但我认为删除实体也会自动将其与任何相关实体分离。
Review
is defined like this:
Review
定义如下:
<?php
class Review extends Eloquent
{
public function products()
{
return $this->belongsToMany('Product');
}
}
Product
is 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 Account
has 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([]);