2014-12-06 52 views
13

使用Laravel,我有以下的代码Laravel雄辩ORM - 多对多删除数据透视表值遗留

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

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

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

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

感谢:

Review的定义如下:

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

Product是这样定义的。

+0

这就是'Eloquent'的工作原理。您可以为数据透视表使用数据库事件('在删除级联上')或使用Eloquent实现您的事件处理程序。就像http://stackoverflow.com/a/14174356/784588 – 2014-12-06 10:44:12

回答

24

的分离方法被用来释放从枢轴表的关系,而删除将删除模型记录本身即,在评论表中的记录。我的理解是,删除不会隐式触发分离。您可以使用model events触发数据透视表的清理,但是,使用类似:

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

另外,我建议的关系将是一对多,作为一个产品都将会有许多评论,但一次审查不会属于许多产品(通常)。

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

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

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

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

编辑:在添加约束,推动清理工作到数据库,并且不必担心在代码中处理它。

+0

在你的第一部分中,你不会迭代结果,而只需调用'$ model-> relation() - > detach()'什么会删除所有的在单个查询中为给定的“$ model”旋转关联。 – 2014-12-06 13:54:39

+0

非常感谢。这完全回答了我的问题。顺便说一句,我有多对多的关系,因为我有一个现有的产品评论清单,有些人已经审查了多件产品的一件。 – 2014-12-07 07:57:44

+0

如果在detach()'语法中加上要分离的item的ID,以及[detach function]的链接,就会很棒(http://laravel.com/api/5.1/Illuminate/Database/Eloquent/Relations/ BelongsToMany.html#method_detach)或[示例](http://laravel.com/docs/5.1/eloquent-relationships#inserting-many-to-many-relationships) – QuickDanger 2015-07-30 07:09:58

5

简单的步骤:

在这个例子中的Account有许多Tags

要删除的标签,然后帐户做到这一点:

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

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

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

然而$review->product()->detach()是非常明确的。