softDelete & $belongsToMany relationship


Let’s say I have two models : Product and Invoice, both using the SoftDelete trait.

They are having a $belongsToMany relationship (xyz_plugin_product_invoice table with product_id and invoice_id).

Now, if I delete (softdelete) a Product, I need my pivot table to be updated as well.

I can’t let the pivot records pending in that table (this could cause an error if I try to access a Product attribute through an invoice),

I see two options :

Whenever a product or invoice is soft-deleted :

  1. the pivot table records are hard deleted.
  2. the pivot table records are soft-deleted.

Options 1 :

I could hook in the model BeforeDelete() function but I would prefer to keep it binded to the relationship.

Options 2 :

This won’t work :

'invoices' => [
            'table' => 'xyz_plugin_product_invoice',
            'softDelete' => 'true'

So I tried to add a pivot model ProductInvoice, that use SoftDelete trait with $belongsTo invoice and product.

Then, on the Product model, I did this :

'invoices' => [
            'pivotModel' => [ProductInvoice::class, 'softDelete' => true, 'key' => 'product_id'],

But when I delete a Product, it’s not soft deleted.

Thanks for your suggestions/ideas.

When either is restored, this relationship will persist by keeping the pending records and this is by design. Requiring this table entry to be deleted is custom behaviour. So, you will need to detach() when you delete or using the afterDelete event override. (Option 1)

1 Like

Thanks @daftspunky

I would like to add for anybody that reads this in the future : even if the pivot table keeps the link between the two records, your query will returns (by default) only the non-trashed.

ex: you have an Invoice with 4 Products. Doing :

$products = $invoice->products; 

$products will contains 4 Products in the collection. Now if you delete one Product, and do :

$products = $invoice->products; 

$products will contains 3 Products in the collection. Even if the link exist in the pivot table.