2014-12-06 116 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()是非常明確的。