2017-06-05 74 views
0

當我通過一個聯結表將belongs-to-many實體與belongsToMany-> link()函數鏈接時,聯結表上的afterSaveCommit事件不會觸發。 link()函數似乎總是在事務中調用save(),並且我無法找到它將在afterSaveCommit之後調用的位置,因爲實體沒有頂級save()調用。在調用鏈接()調用中的SaveCommit之後調用

這是一個疏忽還是通過設計?

回答

0

在多次閱讀代碼並對其進行了深入研究之後,我認爲「它應該」的問題在雙方都有爭論。

我發佈我的解決方案,希望它能幫助別人。

我在ElasticSearch存儲庫中保存非規格化的邏輯記錄副本以供分析,目標是在任何參與的關係實體更改時自動同步ES。所有相關實體都使用afterSave觸發器來同步ES。核心邏輯記錄與靜態數據列表有很多belongsToMany關係,所以有很多連接表和對link()的調用。 ES記錄在每個記錄之後正在更新,這個記錄花費了過多的時間。

我使用了afterSave事件,該事件始終被觸發,然後使用以下代碼創建一個放置在所有相關表上的行爲,這取決於當頂層實體處於正在運行狀態時選項_primary的行爲被設置爲true保存。事實上,這是Cake用來確定何時觸發afterSaveCommit事件的線索之一。

我確實擔心使用未記錄的帶下劃線的前綴標記,即使它正在傳回選項數組中。

class ElasticSyncBehavior extends Behavior 
{ 
    private static $_suspend_flag = false; 

public function suspend_elastic_sync() { 
    self::$_suspend_flag = true; 
} 

public function resume_elastic_sync() { 
    self::$_suspend_flag = false; 
} 

public function afterSave($event, $entity, $options) { 
    if($options["_primary"]!=true || self::$_suspend_flag==true) { 
     return $entity; 
    } 

    // do synchronization here 

    return $entity; 
} 
public function afterDelete(Event $event, EntityInterface $entity, ArrayObject $options) { 
    if($options["_primary"]!=true || self::$_suspend_flag==true) { 
     return $entity; 
    } 

    // do synchronization here 

    return $entity; 
} 
} 

這迫使相同的行爲,其中頂部實體保存後,其在鏈路()的情況下,是連接表同步時才進行。

我還在那裏添加了刪除事件,既可以處理unlink()調用,也可以級聯刪除。

如果這是我們所期望的,我還會採取一種保護措施來徹底改變行爲。將其作爲行爲的靜態變量允許它在具有行爲的所有實體間共享,即使它們各自具有其自己的事件管理器。