當我通過一個聯結表將belongs-to-many實體與belongsToMany-> link()函數鏈接時,聯結表上的afterSaveCommit事件不會觸發。 link()函數似乎總是在事務中調用save(),並且我無法找到它將在afterSaveCommit之後調用的位置,因爲實體沒有頂級save()調用。在調用鏈接()調用中的SaveCommit之後調用
這是一個疏忽還是通過設計?
當我通過一個聯結表將belongs-to-many實體與belongsToMany-> link()函數鏈接時,聯結表上的afterSaveCommit事件不會觸發。 link()函數似乎總是在事務中調用save(),並且我無法找到它將在afterSaveCommit之後調用的位置,因爲實體沒有頂級save()調用。在調用鏈接()調用中的SaveCommit之後調用
這是一個疏忽還是通過設計?
在多次閱讀代碼並對其進行了深入研究之後,我認爲「它應該」的問題在雙方都有爭論。
我發佈我的解決方案,希望它能幫助別人。
我在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()調用,也可以級聯刪除。
如果這是我們所期望的,我還會採取一種保護措施來徹底改變行爲。將其作爲行爲的靜態變量允許它在具有行爲的所有實體間共享,即使它們各自具有其自己的事件管理器。