2014-11-24 52 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