spatie/laravel-model-cleanup
Deprecated: use Laravel’s built-in Prunable. Spatie’s laravel-model-cleanup deletes unneeded Eloquent records via a cleanUp() configuration per model, and an artisan command to prune records older than a given age or matching custom rules.
Installation:
composer require spatie/laravel-model-cleanup
Publish the config file:
php artisan vendor:publish --provider="Spatie\ModelCleanup\ModelCleanupServiceProvider"
Configure Models:
Edit config/model-cleanup.php to register your models under the models key:
'models' => [
\App\Models\YourModel::class,
],
Define Cleanup Logic:
Implement the GetsCleanedUp interface and cleanUp() method in your model:
use Spatie\ModelCleanup\GetsCleanedUp;
use Spatie\ModelCleanup\CleanupConfig;
class YourModel extends Model implements GetsCleanedUp
{
public function cleanUp(CleanupConfig $config): void
{
$config->olderThanDays(5); // Example: Delete records older than 5 days
}
}
Run Cleanup: Execute the Artisan command:
php artisan cleanup:models
Use this package to automate cleanup of stale records (e.g., logs, temporary data, or expired entries). For example, delete old FailedJob records or Sessions after 30 days.
Basic Cleanup:
Define cleanup rules in cleanUp() using CleanupConfig:
$config->olderThanDays(7); // Delete records older than 7 days
$config->olderThanHours(24); // Delete records older than 24 hours
Conditional Cleanup: Use closures to filter records dynamically:
$config->where(function ($query) {
$query->where('status', 'archived');
})->olderThanDays(30);
Batch Processing: Process cleanup in chunks to avoid locking tables:
$config->chunk(100); // Process 100 records at a time
Scheduling:
Add a scheduled task in app/Console/Kernel.php:
$schedule->command('cleanup:models')->daily();
public function handle()
{
$deleted = Artisan::call('cleanup:models');
Log::info("Deleted {$deleted} records via cleanup:models");
}
$model = new YourModel();
$config = Mockery::mock(CleanupConfig::class);
$model->cleanUp($config);
$config->shouldHaveReceived('olderThanDays', [5]);
SoftDeletes for safer cleanup:
$config->olderThanDays(30)->softDelete();
No Maintenance:
The package is archived—use Laravel’s built-in prunable models instead (recommended for new projects).
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Contracts\Prunable;
class YourModel extends Model implements Prunable
{
use SoftDeletes;
public static function prune()
{
static::where('created_at', '<=', now()->subDays(5))->delete();
}
}
Config Registration:
Forgetting to register models in config/model-cleanup.php will skip their cleanup.
Performance:
Large tables may cause timeouts. Use chunk() or run during off-peak hours.
Transactions: Cleanup runs without transactions by default. For critical data, wrap in a transaction:
DB::transaction(function () {
Artisan::call('cleanup:models');
});
--dry-run to the command to preview deletions:
php artisan cleanup:models --dry-run
config/model-cleanup.php:
'debug' => env('APP_DEBUG', false),
Custom Cleanup Logic:
Extend CleanupConfig for reusable rules:
$config->custom(function ($query) {
$query->where('is_active', false)->whereNull('deleted_at');
});
Event Listeners: Trigger events before/after cleanup:
// In EventServiceProvider
ModelCleanupStarting::class => function ($event) {
Log::info('Starting cleanup for ' . $event->model);
},
Dynamic Config: Load cleanup rules from a database or cache for flexibility.
How can I help you explore Laravel packages today?