nebo15/eloquent.changelog
Laravel package that adds changelog/history tracking to Eloquent models. Record changes to attributes and keep an audit trail you can query later, useful for debugging, compliance, and reviewing edits over time.
Installation:
composer require nebo15/eloquent-changelog
Add the service provider to config/app.php:
'providers' => [
// ...
Nebo15\EloquentChangelog\EloquentChangelogServiceProvider::class,
],
Publish Config:
php artisan vendor:publish --provider="Nebo15\EloquentChangelog\EloquentChangelogServiceProvider"
Configure config/eloquent-changelog.php (default: audit_table = changelogs).
First Use Case: Enable changelogging for a model:
use Nebo15\EloquentChangelog\ChangelogTrait;
class User extends Model
{
use ChangelogTrait;
}
Now, any changes to User (create/update/delete) will be logged to the changelogs table.
Automatic Logging:
ChangelogTrait) hooks into Eloquent’s lifecycle events (creating, updating, deleting, saved, restored).$user = User::find(1);
$user->name = "Updated Name"; // Change logged automatically.
$user->save();
Manual Logging:
$user->logChange('email', 'old@example.com', 'new@example.com');
Querying Changes:
$changes = User::changelog()->where('user_id', 1)->get();
$emailChanges = User::changelog()
->where('field', 'email')
->where('action', 'update')
->latest()
->get();
Integration with Observers:
class UserObserver
{
public function logging($model)
{
$model->logChange('status', 'inactive', 'active', ['reason' => 'manual_activation']);
}
}
Soft Deletes:
Changelog) to track restores:
class Changelog extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
}
Performance Overhead:
class Product extends Model
{
use ChangelogTrait;
protected $changelogEnabled = false; // Disable for bulk operations.
}
Missing Fields in Logs:
old_values and new_values are serialized correctly. Override the trait’s getChangelogData() method if custom logic is needed:
protected function getChangelogData()
{
return [
'old_values' => json_encode($this->getOriginal()),
'new_values' => json_encode($this->attributesToArray()),
];
}
Timestamp Precision:
created_at for timestamps. For auditing, ensure your server’s timezone is consistent (config/app.php).Foreign Key Constraints:
changelogs table references a non-existent model ID, logs will fail silently. Validate IDs before logging:
if ($this->exists) {
$this->logChange('field', 'old', 'new');
}
Check Logged Data:
changelogs table directly or dump the changelog model:
dd(User::changelog()->first());
Event Debugging:
Event::listen('eloquent.saving: User', function ($model) {
logger()->debug('Saving user:', $model->toArray());
});
Migration Issues:
changelogs table isn’t created, run:
php artisan vendor:publish --provider="Nebo15\EloquentChangelog\EloquentChangelogServiceProvider" --tag=migrations
php artisan migrate
Custom Changelog Model:
Changelog model to add fields (e.g., user_id for the auditor):
class CustomChangelog extends \Nebo15\EloquentChangelog\Changelog
{
protected $fillable = ['user_id', 'ip_address'];
}
'model' => \App\Models\CustomChangelog::class,
Prevent Logging for Specific Fields:
getChangelogIgnoreFields():
protected function getChangelogIgnoreFields()
{
return ['password', 'remember_token'];
}
Add Metadata:
logChange method:
$user->logChange('status', 'pending', 'approved', [
'auditor_id' => auth()->id(),
'notes' => 'Approved via admin panel',
]);
$changes = User::changelog()
->whereJsonContains('metadata->notes', 'Approved')
->get();
Soft Deletes for Models:
deleted_at:
$user->delete(); // Logs the deletion.
$user->restore(); // Logs the restore if the Changelog model also uses SoftDeletes.
How can I help you explore Laravel packages today?