IT story

라 라벨이 피벗 테이블에 여러 레코드를 추가하는 것을 방지

hot-time 2020. 9. 12. 11:34
반응형

라 라벨이 피벗 테이블에 여러 레코드를 추가하는 것을 방지


내가 사용하는 장바구니에 항목을 추가하기 위해 다 대다 관계를 설정하고 작업 중입니다.

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

피벗 테이블에 항목을 추가하지만 사용자가 이미 추가 한 항목을 추가하기 위해 링크를 다시 클릭하면 피벗 테이블에 중복 항목이 생성됩니다.

레코드가 아직 존재하지 않는 경우에만 피벗 테이블에 레코드를 추가하는 기본 방법이 있습니까?

그렇지 않은 경우 일치하는 레코드가 이미 있는지 찾기 위해 피벗 테이블을 어떻게 확인할 수 있습니까?


다음과 같이 매우 간단한 조건을 작성하여 기존 레코드의 존재를 확인할 수 있습니다.

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

또는 / 그리고 데이터베이스에 단일성 조건을 추가 할 수 있습니다. 이중선을 저장하는 동안 예외가 발생합니다.

또한 바로 아래 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) {}

이 모든 답변이 내가 모든 답변을 시도했기 때문에 좋은 것처럼 여전히 답변이 없거나 처리되지 않은 한 가지가 있습니다. 이전에 확인한 값을 업데이트하는 문제입니다 (선택된 상자를 선택하지 않음). 위의 질문과 비슷한 것이 내 제품 기능 테이블 (피벗 테이블)에서 제품의 기능을 확인하고 선택 취소하고 싶습니다. 나는 초보자이고 위의 어느 것도 그렇게하지 않았다는 것을 깨달았습니다. 새 기능을 추가 할 때는 둘 다 좋지만 기존 기능을 제거하고 싶을 때 (즉 선택 취소)

나는 이것에 대한 어떤 깨달음을 감사드립니다.

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

그냥 사용할 수 있습니다

$cart->items()->sync($items)

Laravel 5.7 기준 :

Syncing Associations You may also use the sync method to construct many-to-many associations. The sync method accepts an array of IDs to place on the intermediate table.Any IDs that are not in the given array will be removed from the intermediate table. So, after this operation is complete, only the IDs in the given array will exist in the intermediate table:


There are some great answers posted already. I wanted to throw this one out here as well though.

The answers from @AlexandreButynski and @Barryvdh are more readable than my suggestion, what this answer adds is some efficiency.

It retrieves only the entries for the current combination (actually only the id) and it than attaches it if it does not exist. The sync method (even without detaching) retrieves all currently attached ids. For smaller sets with little iterations this will hardly be a difference, ... you get my point.

Anyway, it is definitely not as readable, but it does the trick.

if (is_null($book->authors()->find($author->getKey(), [$author->getQualifiedKeyName()])))
    $book->authors()->attach($author);

참고URL : https://stackoverflow.com/questions/17472128/preventing-laravel-adding-multiple-records-to-a-pivot-table

반응형