2014-11-24 60 views
4

我想跟踪(记录)对每个数据库行所做的更改。这意味着,为每个表的每条记录保存每个操作的日志(插入,更新,删除)。如何捕捉数据透视表中的模型事件

此问题已解决模型,因为它们从BaseModel延伸,我使用model events。但是,我似乎无法找到一种方法来记录从数据透视表更改。

鉴于下表usersprofilesprofile_user(profile_id, user_id),我有以下代码:

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); 
     }); 
    } 
} 

这让我从profile_user记录从userprofile但没有改变。

我试图创建一个ProfileUser模型,该模型从PivotIlluminate\Database\Eloquent\Relations\Pivot)开始,其中我定义了模型事件但没有起作用。

我猜这是因为我从来没有创建这个模型的新实例。所以,我增加了以下我User模型(以及类似的代码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); 
    } 
    // (...) 
} 

不过,这些事件从未被触发。

我通过sync()更新的关系:

$user->profiles()->sync(explode(',', $values["profiles"])); 

我找不涉及发射了自定义事件(因为这意味着我将不得不为每个数据透视表做到这一点的解决方案在数据库中)。

如何在透视表中使用模型事件?

+0

你不能做到这一点与口才的事件,因为'attach'方法依赖在'Query \ Builder'和简单插入(它在'sync'后面被调用)。顺便说一句,这些关系有什么关系? '发布属于子类别'和'子类别belongsToMany发布'??这是错误的,除非你只是犯了一个错字。 – 2014-11-28 23:43:32

+0

@JarekTkaczyk对不起,我有没有使用的关系,并选择了错误的例子。我用一个正确的例子更新了代码。你知道有什么办法做到这一点吗? – 2014-11-29 00:53:21

+0

你需要这个包https://github.com/fico7489/laravel-pivot – fico7489 2017-12-03 22:25:25

回答

2

我知道你不想要自定义事件的情况,但我找不到任何非自定义解决方案。

但是你可以做一个非常简单的自定义一个(几乎从Laravel文档右拉):

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

+2

使用'illuminate.query'可能是最后的资源解决方案。正如我所看到的,模型事件的优点是您可以获得模型并且可以使用'$ model-> getTable()'和'$ model-> isDirty()'。有了这个解决方案,我必须解析'$ sql'来确定它是否是插入,更新或删除,解析表名并处理绑定。 – 2014-11-25 10:52:57