Search code examples
laraveleloquentlaravel-7

Deleting a relational item if it's not in the request in Laravel


I have a quote in Laravel where the form has add and remove buttons (form repeater). My problem is that if I remove an item when I update a quote, it does not delete items linked to the quote in the database that is not part of the request on save and simply leaves the item stored in the database. Here is my query that I run on the save when editing a form:

foreach (request('quoteItems') as $quoteItem => $item) {
          $assignedItem = QuoteItems::where('id',$quoteItem)->first();
          $assignedItem->id = $item['id'];
          $assignedItem->price = $item['price'];
          $assignedItem->cost = $item['cost'];

          if (QuoteItems::where('quote_id', $quote->id)->where('id', $item['id'])) {
            $assignedItem->save();
          } else {
            QuoteItems::where('quote_id', $id)->delete();
          }
        } 

I know this can be solved by using pivot methods, but the problem with pivots is the same foreign key item (QuoteItem in this case) cannot be added twice in a quote and that is something I absolutely need to be able to do. I don't understand what is wrong with my query as in theory it should delete items not in the request. Updates save fine but removed items do not delete.

Would appreciate it if someone can help me out here.


Solution

  • I believe you want to remove the quote items that are not in the request.

    So you might want to do something like this:

    foreach (request('quoteItems') as $quoteItem => $item) {
        $assignedItem = QuoteItems::where('id',$quoteItem)->first();
        $assignedItem->id = $item['id'];
        $assignedItem->price = $item['price'];
        $assignedItem->cost = $item['cost'];
        $assignedItem->save();
    }
    
    QuoteItems::where('quote_id', $quote->id)
        ->whereNotIn('id', array_keys(request('quoteItems')))
        ->get()
        ->each
        ->delete();