防止Laravel将多个logging添加到数据透视表

我有一个多对多的关系设置和工作,添加一个项目,我用的车:

$cart->items()->attach($item); 

它将一个项目添加到数据透视表(应该如此),但是如果用户再次点击链接添加一个他们已经添加的项目,它会在数据透视表中创build一个重复的项目。

是否有内置的方式来添加一个数据透视表,只有当一个不存在?

如果没有,我怎样才能检查数据透视表,find一个匹配的logging是否已经存在?

你可以通过写这样一个非常简单的条件来检查现有logging的存在:

 if (! $cart->items->contains($newItem->id)) { $cart->items()->save($newItem); } 

或者/你可以在你的数据库中添加unicity条件,在试图保存一个doublet的时候会抛出一个exception。

你也应该看看下面的Barryvdh更直接的答案。

您也可以使用$model->sync(array $ids, $detaching = true)方法并禁用分离(第二个参数)。

 $cart->items()->sync([$item->id], false); 

更新:由于Laravel 5.3或5.2.44,你也可以调用syncWithoutDetaching:

 $cart->items()->syncWithoutDetaching([$item->id]); 

这完全一样,但更可读:)

@alexandre Butynsky方法工作得很好,但使用两个SQL查询。

一个用来检查购物车是否包含该项目,另一个用于保存。

要只使用一个查询使用这个:

 try { $cart->items()->save($newItem); } catch(\Exception $e) {} 

尽pipe所有这些答案都是因为我尝试了所有的答案,但还是有一件事情没有得到解决:更新先前选中的值的问题(取消选中checkbox[es])。 我有类似于上述问题,希望我想要检查和取消我的产品function表(数据透视表)中的产品function。 我是一个新手,我已经意识到上述没有做到这一点。 添加新function的时候都不错,但是当我想删除现有function的时候(比如取消选中)

对此我将感激不尽的启示。

 $features = $request->get('features'); if (isset($features) && Count($features)>0){ foreach ($features as $feature_id){ $feature = Feature::whereId($feature_id)->first(); $product->updateFeatures($feature); } } //product.php (extract) public function updateFeatures($feature) { return $this->features()->sync($feature, false); } 

要么

 public function updateFeatures($feature) { if (! $this->features->contains($features)) return $this->features()->attach($feature); } //where my attach() is: public function addFeatures($feature) { return $this->features()->attach($feature); } 

对不起,我不应该删除这个问题,因为自己找出答案,这听起来有点愚蠢,上面的答案就像工作@Barryvdh sync()一样简单,如下所示; 阅读了越来越多的关于:

 $features = $request->get('features'); if (isset($features) && Count($features)>0){ $product->features()->sync($features); }