Предотвращение Laravel добавления нескольких записей в сводную таблицу

У меня есть много разных отношений, настроенных и работающих, чтобы добавить элемент в корзину, которую я использую:

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

Что добавляет элемент в сводную таблицу (как и должно быть), но если пользователь снова нажимает на ссылку, чтобы добавить элемент, который они уже добавили, он создает дублируемую запись в сводной таблице.

Есть ли встроенный способ добавления записи в сводную таблицу только в том случае, если ее еще нет?

Если нет, как я могу проверить сводную таблицу, чтобы найти, существует ли соответствующая запись?

Ответ 1

Вы можете проверить наличие существующей записи, написав очень простое условие, подобное этому:

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

Или/и вы можете добавить условие единства в своей базе данных, оно будет генерировать исключение во время попытки сохранения дублета.

Вы также должны взглянуть на более простой ответ от Barryvdh чуть ниже.

Ответ 2

Вы также можете использовать метод $model->sync(array $ids, $detaching = true) и отключить отключение (второй параметр).

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

Обновление: Начиная с Laravel 5.3 или 5.2.44, вы также можете вызвать syncWithoutDetaching:

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

Что делает то же самое, но более читаемым:)

Ответ 3

@alexandre Бутынский метод работает очень хорошо, но использует два sql-запроса.

Один, чтобы проверить, содержит ли корзина элемент и тот, который нужно сохранить.

Чтобы использовать только один запрос, используйте это:

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

Ответ 4

Насколько я понимаю, все эти ответы связаны с тем, что я все их пробовал, одна вещь по-прежнему остается без ответа или не заботится о ней: проблема обновления ранее проверенного значения (снятие флажка с флажком [es]). У меня есть что-то похожее на вышеупомянутый вопрос. Ожидайте, что я хочу проверить и снять отметку с функциями продуктов в моей таблице характеристик продукта (сводной таблице). Я новичок, и я понял, что ничего из этого не сделал. Они хороши при добавлении новых функций, но не тогда, когда я хочу удалить существующие функции (т.е. Снимите флажок)

Я буду благодарен за любое просвещение в этом.

$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);
}