I want to track (record) the changes made to each database row. This means, saving a log of each action (insert, update, delete) made to each record of each table.
This issue is solved for models, as they extend from a BaseModel
and I'm using model events. However, I cannot seem to find a way to record the changed from pivot tables.
Given the following tables users
, profiles
and profile_user(profile_id, user_id)
, I have the following code:
class User extends BaseModel {
public function profiles() {
return $this->belongsToMany('Profile');
}
}
class Profile extends BaseModel {
public function users() {
return $this->belongsToMany('User');
}
}
abstract class BaseModel extends Model {
public static function boot() {
parent::boot();
static::created(function($model) {
return LogTracker::saveRowCreatedOrUpdated($model, true);
});
static::updated(function($model) {
return LogTracker::saveRowCreatedOrUpdated($model, false);
});
static::deleted(function($model) {
return LogTracker::saveRowDeleted($model);
});
}
}
This allows me to record the changes from user
and profile
but not from profile_user
.
I've tried to create a ProfileUser
model that extends from Pivot
(Illuminate\Database\Eloquent\Relations\Pivot
) where I defined the model events but that didn't work.
I'm guessing that's because I never create a new instance of this model. So, I've added the following to my User
model (and similar code to Profile
):
class User extends BaseModel {
// (...)
public function newPivot(Eloquent $parent, array $attributes, $table, $exists) {
if ($parent instanceof Profile) {
return new ProfileUser($parent, $attributes, $table, $exists);
}
return parent::newPivot($parent, $attributes, $table, $exists);
}
// (...)
}
Still, the events are never fired (actually this method is never executed).
I am updating the relationship through sync()
:
$user->profiles()->sync(explode(',', $values["profiles"]));
I'm looking for a solution that doesn't involve firing a custom event (as this means that I would have to do this for each pivot table in database).
How can I use model events in pivot tables?
I am aware you don't want a custom event situation but I cannot find any non-custom solution.
You can however do a very simple custom one (pretty much pulled right from Laravel docs):
DB::listen(function($sql, $bindings, $time)
{
//regex matching for tables in SQL query
//as well as firing your event handling code
});
http://laravel.com/docs/4.2/database#running-queries
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With