Eloquent: How to auto-delete old records after N days

Updated: January 25, 2024 By: Guest Contributor Post a comment

Introduction

When developing applications, it’s a common requirement to maintain a clean database by automatically removing old records. In this tutorial, we’ll explore how to set up an automatic deletion mechanism for records with Laravel’s ORM, Eloquent, after a certain number of days.

Understanding Eloquent Pruning

Eloquent ORM, Laravel’s in-built ORM, provides eloquent models that represent the tables in your database. With Laravel 8.x and later, a feature called model pruning has been introduced which can help in this exact scenario.

Auto-pruning: The Basics

To leverage this feature, your model should use the Illuminate\Database\Eloquent\Prunable trait. This trait provides the necessary method that you will override to define when records should be considered stale and pruned.

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Prunable;

class YourModel extends Model
{
    use Prunable;

    protected function pruning() {
        return $this->where('created_at', '<=', now()->subDays(30));
    }
}

Here, as an example, pruning method is defined to auto-delete records older than 30 days. The method uses Carbon’s subDays to compute the date and the where clause to filter the records that should be pruned.

Setting Up Scheduled Pruning

To automatically trigger the pruning process, you’ll set up a scheduler in Laravel that runs the prune command.

// App\Console\Kernel.php

protected function schedule(Schedule $schedule)
{
    $schedule->command('model:prune', [
        '--model' => [YourModel::class],
    ])->daily();
}

This will schedule the pruning process to occur daily. However, you can adjust the frequency as per your requirements by using methods like hourly, weekly, etc.

Automating Scheduled Tasks

After defining the schedule, don’t forget to set up the task scheduler’s cron entry on your server to run the Laravel scheduler.

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

It will run the schedule:run command every minute to check if any scheduled commands are due.

Advanced Pruning Conditions

Beyond the basic usage, you might want to extend the logic to handle more complex scenarios, such as soft-deleted records. Depending on your application logic, you can refine the query inside the pruning method further.

// If you're using SoftDeletes and want to prune soft deleted records...
protected function pruning() {
    return $this->onlyTrashed()->where('deleted_at', '<=', now()->subDays(30));
}

Manually Triggering Pruning

While it is efficient to schedule pruning, you may also need to manually initiate the process during development or other operations.

php artisan model:prune --model=\App\Models\YourModel

You will see a confirmation message once the pruning is complete.

Handling Pruning Events

Laravel fires events before and after pruning: eloquent.prune: *your model class* and eloquent.pruned: *your model class*, which you can listen for in your application:

Event::listen('eloquent.prune: App\Models\YourModel', function ($model) {
    // Do stuff before pruning
});
Event::listen('eloquent.pruned: App\Models\YourModel', function ($model) {
    // Do stuff after pruning
});

Custom Pruning Logic

Perhaps you need to take action on other tables or logic when pruning occurs; you can override the pruneAll method to customize behavior fully.

protected function pruneAll()
{
    // Your custom logic for pruning.
}

Pruning Strategy Considerations

Before implementing pruning, consider the size of the table, frequency of prunes, and business logic to ensure the application’s stability and performance is not affected. Backup your database at regular intervals to avoid accidental data loss.

Conclusion

In this tutorial, we’ve covered how to automatically delete old Eloquent records after a specified number of days. Regular pruning of outdated information can result in leaner databases, potentially lower storage costs, and often better performance. Make sure to thoroughly test any pruning strategy in a non-production environment before deploying it to ensure it works exactly as expected.