How7o
  • Home
  • Tools
  • Prank Screens
  • Contact
  • Blog
Reading: How to Delete a Record with Laravel Eloquent (4 Methods)
Share
Subscribe Now
How7oHow7o
Font ResizerAa
  • Marketing
  • OS
  • Features
  • Guide
  • Complaint
  • Advertise
Search
  • Home
  • Tools
  • Prank Screens
  • Contact
  • Blog
Follow US
Copyright © 2014-2023 Ruby Theme Ltd. All Rights Reserved.
How7o > Blog > Web Development > How to Delete a Record with Laravel Eloquent (4 Methods)
Web Development

How to Delete a Record with Laravel Eloquent (4 Methods)

how7o
By how7o
Last updated: April 20, 2026
6 Min Read
Laravel Eloquent delete record — trash-bin icon next to User::destroy code snippet
SHARE

There are four common ways to laravel eloquent delete record rows from the database, and picking the right one matters for performance, model events, and soft-delete behaviour. This guide walks through each — find-then-delete, the shorthand destroy(), mass delete via the query builder, and force-deleting soft-deleted models — with working code you can drop into a controller.

Contents
  • TL;DR
  • Method 1 — find and delete
    • Using the result as a truthy check
  • Method 2 — destroy() by key
  • Method 3 — mass delete via the query builder
  • Method 4 — soft deletes and forceDelete
  • Frequently asked questions
  • Related guides
  • References

Last verified: 2026-04-21 on Laravel 11 with PHP 8.3. Originally published 2022-08-30, rewritten and updated 2026-04-21.

TL;DR

Use User::destroy($id) for the simplest “delete by primary key” case. Use $user->delete() when you already have the model loaded. Use User::where(...)->delete() for fast bulk deletes without firing events. Use $user->forceDelete() to permanently remove soft-deleted rows.

Method 1 — find and delete

The most explicit form: fetch the model, then call delete() on it. Model events (deleting, deleted) fire normally, and any soft-delete trait on the model is respected.

User::where('id', '=', $user_id)->first()->delete();

One catch: if no row matches, first() returns null and the ->delete() call throws a null-reference error. For a safer idiom, use findOrFail() — it throws a ModelNotFoundException that Laravel turns into a 404 by default:

User::findOrFail($user_id)->delete();

Using the result as a truthy check

Instance delete() returns a boolean, so you can branch on success directly. Here’s a typical JSON-API response pattern:

if (User::where('id', '=', $user_id)->first()->delete()) {
    return response()->json(['status' => 1, 'msg' => 'success']);
} else {
    return response()->json(['status' => 0, 'msg' => 'fail']);
}

Method 2 — destroy() by key

destroy() is a static shortcut that takes one or more primary keys, loads the matching models, and deletes them. Model events fire for each.

User::destroy($user_id);
// or a batch:
User::destroy([1, 2, 3]);
User::destroy(1, 2, 3);

It returns the number of rows deleted. Under the hood it’s equivalent to fetching each model with find() and calling delete() on it — the cost is one SELECT per chunk plus one DELETE per row.

laravel eloquent delete record — find-delete, destroy, mass where-delete, forceDelete decision tree

Method 3 — mass delete via the query builder

When you’re deleting many rows and don’t need model events, skip the instantiation step entirely:

$deleted = User::where('last_login_at', '<', now()->subYear())->delete();
// $deleted is an int — the number of rows affected

This emits a single DELETE FROM users WHERE last_login_at < ? statement. No model instances are hydrated, no deleting/deleted events fire, and no single-model observers run. Use this form for cleanup jobs and batch purges; avoid it when downstream code relies on model events (for example, cache invalidation hooked into deleted).

Method 4 — soft deletes and forceDelete

If your model uses the Illuminate\Database\Eloquent\SoftDeletes trait, delete() does not actually remove the row — it sets the deleted_at timestamp and excludes the row from future queries by default. To purge it permanently:

// soft delete (sets deleted_at):
$user->delete();

// permanently remove:
$user->forceDelete();

// restore a soft-deleted row:
$user = User::withTrashed()->findOrFail($user_id);
$user->restore();

When a soft-deleted row needs to cascade to related rows, that’s a separate concern — see the cascade delete guide for the migration-level and event-listener approaches.

Frequently asked questions

What’s the difference between destroy() and where()->delete()?

Model::destroy($id) first fetches the model, fires deleting/deleted events, then deletes. Model::where(...)->delete() runs a single DELETE statement without instantiating anything, which is much faster for bulk deletes but does not fire model events or respect single-model observers. Pick based on whether you need the events.

Does delete() return true/false or the affected row count?

It depends on the call. On an instance ($model->delete()) it returns a boolean. On a query builder (Model::where(...)->delete()) it returns an integer — the number of rows affected. Both can be used as truthy checks, which is what the snippet in the post does, but knowing the shape helps when you want to log how many rows went.

How do I permanently delete a soft-deleted record?

If the model uses the SoftDeletes trait, delete() only sets the deleted_at column. To remove the row from the table, call forceDelete() instead: $user->forceDelete(). To restore a soft-deleted row, use $user->restore() after retrieving it with withTrashed().

Why does User::where(...)->first()->delete() throw a null error?

Because first() returns null when no row matches, and you can’t call delete() on null. Use findOrFail($id) to throw a 404 on miss, or guard with optional($user)->delete(), or switch to User::where(...)->delete() which returns 0 safely when nothing matches.

How do I cascade deletes to related rows?

Two options. At the database level, define ->constrained()->cascadeOnDelete() in your migrations so MySQL handles it. At the application level, hook the deleting model event and delete related rows inside it. I cover both in the cascade delete guide.

Related guides

  • How to Install Laravel on Ubuntu — set up the framework before running delete operations.
  • How to Automatically Delete Related Rows in Laravel — cascading deletes to child tables.
  • How to Check If a Record Exists in Laravel — guard pattern before delete to avoid null errors.

References

Official Eloquent deletion docs: laravel.com/docs/eloquent. Query-builder delete behaviour: laravel.com/docs/queries.

TAGGED:EloquentLaravelmysqlphpsql

Sign Up For Daily Newsletter

Be keep up! Get the latest breaking news delivered straight to your inbox.
By signing up, you agree to our Terms of Use and acknowledge the data practices in our Privacy Policy. You may unsubscribe at any time.
Share This Article
Facebook Copy Link Print
Previous Article Laravel Eloquent multiple where and orWhere — closure-grouped query snippet with parenthesis highlight How to Combine Multiple where() and orWhere() in Laravel Eloquent
Next Article Laravel Eloquent count rows — Post::count query snippet with aggregate bar chart icon How to Count Rows in Laravel Eloquent Efficiently
Leave a Comment

Leave a Reply Cancel reply

You must be logged in to post a comment.

FacebookLike
XFollow
PinterestPin
InstagramFollow

Subscribe Now

Subscribe to our newsletter to get our newest articles instantly!
Most Popular
Laravel left outer join — query builder leftJoin illustration with two tables
How to Do a Left Outer Join in Laravel Query Builder
April 20, 2026
Laravel last inserted ID — Eloquent save populates model primary key illustration
How to Retrieve the Last Inserted ID in Laravel Eloquent
April 20, 2026
Laravel Eloquent records today — Carbon today helper and whereDate illustration
How to Get Records Created Today in Laravel
April 20, 2026
Laravel Eloquent current month records — calendar and query builder illustration
How to Get Current Month Records in Laravel Eloquent
April 20, 2026
Laravel Eloquent group by count — Book::groupBy('author') query with bar-chart aggregate icon
How to Count Records Grouped By a Column in Laravel Eloquent
April 20, 2026

You Might Also Like

Include Composer packages in plain PHP projects
Web Development

How to Include Composer Packages in Plain PHP Projects (Autoload + Example)

5 Min Read
How to use localStorage in JavaScript shown in a browser storage panel
Web Development

How to Use localStorage in JavaScript (With Real Examples + Troubleshooting)

8 Min Read
Replace Broken Images Automatically with JavaScript
Web Development

Replace Broken Images Automatically with JavaScript (and jQuery)

5 Min Read
Send a simple email in Laravel using Mail::raw and SMTP
Web Development

How to Send a Simple Email in Laravel (Fast SMTP + Mail::raw)

4 Min Read
How7o

We provide tips, tricks, and advice for improving websites and doing better search.

Latest News

  • SEO Audit Tool
  • Client ReferralsNew
  • Execution of SEO
  • Reporting Tool

Resouce

  • Google Search Console
  • Google Keyword Planner
  • Google OptimiseHot
  • SEO Spider

Get the Top 10 in Search!

Looking for a trustworthy service to optimize the company website?
Request a Quote
Welcome Back!

Sign in to your account

Username or Email Address
Password

Lost your password?