PHP

Implementing Soft Deletes with Eloquent and Related Models

Learn to use Laravel Eloquent's soft deletes to gracefully remove records by marking them as deleted, and how this impacts related models.

// 1. Add `deleted_at` column to your model's table
// php artisan make:migration add_deleted_at_to_posts_table --table=posts
// In migration:
// Schema::table('posts', function (Blueprint $table) {
//     $table->softDeletes();
// });
// Schema::table('posts', function (Blueprint $table) {
//     $table->dropSoftDeletes();
// });

// 2. Use `SoftDeletes` trait in your Model (e.g., app/Models/Post.php)
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Post extends Model
{
    use SoftDeletes; // Add this trait

    protected $fillable = ['title', 'content'];

    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

// 3. Example Usage (e.g., in a controller or route)
use App\Models\User;
use App\Models\Post;

// Create a user and a post
$user = User::factory()->create();
$post1 = $user->posts()->create(['title' => 'My First Post', 'content' => 'Content 1']);
$post2 = $user->posts()->create(['title' => 'My Second Post', 'content' => 'Content 2']);

echo "Initial posts count for user:
";
echo "User " . $user->name . " has " . $user->posts->count() . " posts.
"; // Will show 2

// Soft delete a post
$post1->delete();

echo "
After soft deleting Post 1:
";
echo "User " . $user->name . " has " . $user->posts->count() . " posts (default query).
"; // Will show 1 (soft deleted are excluded by default)
echo "Total posts including soft deleted: " . Post::withTrashed()->count() . "
"; // Will show 2
echo "Only soft deleted posts: " . Post::onlyTrashed()->count() . "
"; // Will show 1

// Access soft deleted relationships (eager loading)
$userWithTrashedPosts = User::with(['posts' => function ($query) {
    $query->withTrashed();
}])->find($user->id);

echo "
User " . $userWithTrashedPosts->name . " has " . $userWithTrashedPosts->posts->count() . " posts (with trashed).
"; // Will show 2

// Restore a soft deleted post
Post::withTrashed()->find($post1->id)->restore();

echo "
After restoring Post 1:
";
echo "User " . $user->name . " has " . $user->posts->count() . " posts.
"; // Will show 2 again
echo "Total posts including soft deleted: " . Post::withTrashed()->count() . "
"; // Will show 2
echo "Only soft deleted posts: " . Post::onlyTrashed()->count() . "
"; // Will show 0
How it works: Soft deletes in Laravel Eloquent allow you to "delete" records without actually removing them from your database. Instead, a `deleted_at` timestamp is set. This snippet demonstrates how to enable soft deletes using the `Illuminate\Database\Eloquent\SoftDeletes` trait, and how it affects querying. By default, soft-deleted records are excluded from query results. You can retrieve them using `withTrashed()` or only retrieve deleted ones using `onlyTrashed()`. It also shows how to restore a soft-deleted record and how to eager load relationships while including or excluding soft-deleted related models.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs