Skip to content

Instantly share code, notes, and snippets.

@orottier
Created November 5, 2015 11:32
Show Gist options
  • Save orottier/ae478a46b3cdde2cc262 to your computer and use it in GitHub Desktop.
Save orottier/ae478a46b3cdde2cc262 to your computer and use it in GitHub Desktop.
Laravel, store changes on your models: TrackChanges Trait
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateChangesTable extends Migration
{
/**
* Run the migrations.
*/
public function up()
{
Schema::create('changes', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->integer('actor_id')->unsigned()->nullable(); //null for CLI
$table->foreign('actor_id')->references('id')->on('users');
// polymorphic
$table->string('object_type');
$table->integer('object_id')->unsigned();
$table->index(['object_type', 'object_id']);
$table->string('attribute');
$table->string('old_value')->nullable();
$table->string('new_value')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down()
{
Schema::drop('changes');
}
}
<?php
namespace App\Traits;
use Auth;
use App\Models\Change;
trait TrackChanges
{
public static function bootTrackChanges()
{
static::updated(function ($object) {
$changes = [];
$now = date('Y-m-d H:i:s');
foreach ($object->getDirty() as $attribute => $value) {
//only store updates of non guarded stuff, i.e. attributes that are mass assignable
if (!in_array($attribute, $object->guarded)) {
//get the old value
$original = $object->getOriginal($attribute);
// skip trivial changes
if ($original !== $object->$attribute) {
$changes[] = [
'object_type' => self::class,
'object_id' => $object->id,
'attribute' => $attribute,
'old_value' => $original,
'new_value' => $object->$attribute, // leave this out if you like normalized tables
'actor_id' => Auth::check() ? Auth::user()->id : null,
'created_at' => $now,
'updated_at' => $now,
];
}
}
}
// bulk insert
Change::insert($changes);
});
}
public function changes()
{
return $this->hasMany(Change::class, 'object_id')->where('object_type', static::class);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment