Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Igeruns's avatar

Why my Laravel on delete cascade is not working?

Why my Laravel "on cascade delete" is not working? Could you help me?

Schema::create('transactions', function (Blueprint $table) {
  ...
  $table->unsignedBigInteger('payment_id');
  $table->foreign('payment_id')->references('id')->on('payments')->onDelete('cascade');
});

Schema::create('payments', function (Blueprint $table) {
  $table->bigIncrements('id');
  ...
});

My engine is InnoDB. 10.4.8-MariaDB, Laravel 6. php mysql laravel

0 likes
11 replies
tykus's avatar

Might sound like a silly question, but which record are you deleting?

Igeruns's avatar

I am deleting Transcation.

public function destroy(Transaction $transaction) { $transaction->delete(); return redirect()->route('transactions.index'); }

RoboRobok's avatar

Please think about it, buddy. Are you expecting the parent to be deleted when you delete the child? That wouldn't make any sense, would it? You need t delete the payment to delete its child transactions. Not the prher way around.

tykus's avatar

I expected as much. You have the wrong understanding; the idea of cascading deletes is that whenever the related record is deleted, the corresponding record(s) from this table are deleted also! Your constraint means that whenever a Payment record is deleted, all of the Transaction records that are related by payment_id will be deleted also.

Igeruns's avatar

Thanks for explanation. However I had tried to delete payment record in phpMyAdmin and cascading delete was not working too. But now it seems more clear to me. I have two foreign keys in transactions table and that's way it's not working when I'm trying to delete payment.

Schema::create('payments', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->bigInteger('account_id');
    $table->decimal('amount', 13, 2);
    $table->timestamps();
});

Schema::create('revenues', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->bigInteger('account_id');
    $table->decimal('amount', 13, 2);
    $table->timestamps();
});

Schema::create('transactions', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->bigInteger('user_id');
    $table->date('date');
    $table->decimal('amount', 13, 2);
    $table->unsignedBigInteger('payment_id');
    $table->unsignedBigInteger('revenue_id');
    $table->bigInteger('category_id');
    $table->bigInteger('subcategory_id');
    $table->string('remarks')->nullable();
    $table->timestamps();
    $table->foreign('payment_id')->references('id')->on('payments')->onDelete('cascade');
    $table->foreign('revenue_id')->references('id')->on('revenues')->onDelete('cascade');
});

So the better approach is to use delete method in controller and delete both records?

public function destroy(Transaction $transaction)
{
    $transaction->delete();

    $payment = Payment::find($transaction->payment_id);
    $payment->delete();

    $revenue = Revenue::find($transaction->revenue_id);
    $revenue->delete();

    return redirect()->route('transactions.index');
}
tykus's avatar

No. Deleting either of the related Payment or Revenue records should cause the Transaction to be deleted.

It's not quite sitting right with me that the relationships are this way; can either a Payment or a Revenue model belong to more than one Transaction?

Igeruns's avatar

No. My logic works that one payment and one revenue belongs to one transaction. It's a home budget tracker.

Snapey's avatar
Snapey
Best Answer
Level 122

Then your keys are wrong. If revenue belongs to transaction then it should have a transaction_id column. Same for revenue. Not the other way around

The belonging to item always has the pointer to the other table

1 like
tykus's avatar

So, this is exactly the point I was making yesterday. The placement of the foreign keys and the Eloquent relationships are indeed backwards according what might be conventional. If it were my app, I would certainly put the FK on the Revenue and Payment models, and define the relationships on the relevant models accordingly.

1 like
dorqa95's avatar

And what if I have an Event and a related Photo model. In event now I have photo_id, and I want to remove the photo from the db when the event is deleted. In the Photo table I store all kind of models photos (Presenter, Issue, Event, Book, etc.). Now I store the pointers in the other side, not in the Photo. Am I able to has a pointer in the Photo table to the actual table? Is that possible?

Thanks for Your help!

Please or to participate in this conversation.