如何捕获数据透视表中的模型事件

Luí*_*ruz 5 model laravel eloquent laravel-4

我想跟踪(记录)对每个数据库行所做的更改.这意味着,保存对每个表的每个记录所做的每个操作(插入,更新,删除)的日志.

这个问题已经解决了,因为它们来自于BaseModel我正在使用的模型事件.但是,我似乎找不到记录透视表更改的方法.

鉴于以下表格users,profilesprofile_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);
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

这让我记录的变化从userprofile而不是从profile_user.

我试图创建一个ProfileUserPivot(Illuminate\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);
    }
    // (...)
}
Run Code Online (Sandbox Code Playgroud)

但是,事件永远不会被触发(实际上这个方法永远不会被执行).

我通过sync()以下方式更新关系:

$user->profiles()->sync(explode(',', $values["profiles"]));
Run Code Online (Sandbox Code Playgroud)

我正在寻找一个不涉及触发自定义事件的解决方案(因为这意味着我必须为数据库中的每个数据透视表执行此操作).

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

小智 3

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

然而,你可以做一个非常简单的自定义(几乎直接从 Laravel 文档中提取):

DB::listen(function($sql, $bindings, $time)
{
    //regex matching for tables in SQL query
    //as well as firing your event handling code
});
Run Code Online (Sandbox Code Playgroud)

http://laravel.com/docs/4.2/database#running-queries

  • 使用“Illuminate.query”可能是最后的资源解决方案。在我看来,模型事件的优点是您可以获得模型并能够使用“$model->getTable()”和“$model->isDirty()”。使用此解决方案,我必须解析“$sql”以确定它是插入、更新还是删除,解析表名并处理绑定。 (2认同)