How7o
  • Home
  • Tools
  • Prank Screens
  • Learn
  • Blog
  • Contact
Reading: How to Delete a Record with Laravel Eloquent (4 Methods)
Share
How7oHow7o
Font ResizerAa
  • OS
Search
  • Home
  • Tools
  • Prank Screens
  • Learn
  • Blog
  • Contact
Follow US
© 2024–2026 How7o. All rights reserved.
How7o > Learn > 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.
[mc4wp_form]
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
Most Popular
Display PHP errors — ini_set + php.ini configuration
How to Display PHP Errors
May 10, 2026
PHP convert string to uppercase — strtoupper and mb_strtoupper
How to Convert a String to Uppercase in PHP
May 10, 2026
PHP string to float conversion with cast, regex cleanup, NumberFormatter
How to Convert a String to Float in PHP
May 10, 2026
PHP merge arrays without duplicates — union operator and array_unique
How to Combine Two Arrays Without Duplicates in PHP
May 10, 2026
PHP delete array element — unset, array_splice, array_filter, array_search
How to Delete an Element from a PHP Array
May 10, 2026

You Might Also Like

Laravel Vite combine CSS — @import chain bundles vendor and app stylesheets
Web Development

How to Compile Multiple CSS into One CSS with Laravel + Vite

7 Min Read
CyberPanel too many redirects Laravel error fixed by restarting LiteSpeed
Server Management

Fix CyberPanel Too Many Redirects (ERR_TOO_MANY_REDIRECTS) for Laravel Subdomain

7 Min Read
Install Laravel on Ubuntu — terminal with composer create-project command and Laravel red-pillar icon
Web Development

How to Install Laravel on Ubuntu: Step-by-Step Guide

9 Min Read
WordPress admin notice — four notice types shown at the top of the admin area
Web Development

How to Show Custom Notifications in the WordPress Dashboard

6 Min Read
How7o

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

Tools

  • Age Calculator
  • Word Counter
  • Image Upscaler
  • Password Generator
  • QR Code Generator
  • See all tools→

Pranks

  • Fake Blue Screen Prank
  • Hacker Typer
  • Fake iMessage Generator
  • Windows XP Crash Prank
  • Windows 11 Update Prank
  • See all prank screens →

Company

  • About Us
  • Blog
  • Contact
  • Privacy Policy
  • Terms of Service
  • Sitemap
© 2024–2026 How7o. All rights reserved.
Welcome Back!

Sign in to your account

Username or Email Address
Password

Lost your password?