在 hasMany 中依赖 true 不能在 cakephp4 中的子节点上工作

Posted

技术标签:

【中文标题】在 hasMany 中依赖 true 不能在 cakephp4 中的子节点上工作【英文标题】:dependent true in hasMany not working on children nodes in cakephp4 【发布时间】:2021-11-28 05:17:17 【问题描述】:

我有一个使用 TreeBehavior 和 hasMany Articles 的类别表:

class CategoriesTable extends Table

    public function initialize(array $config): void
    
        parent::initialize($config);

        $this->addBehavior('Tree');
        $this->belongsTo('Categories');
        $this->hasMany('Articles', [
            'dependent' => true
        ]);
    
 

当我删除包含文章的类别“C”时,文章被正确删除,因为我设置了依赖于 true。 但是,如果我删除类别“C”的父项,则不再删除“C”中的文章。 我认为“cascadeCallbacks”会帮助解决这个问题,但它没有......

这很奇怪,因为在 Cakephp2 中它起作用了。

如何告诉 CakePHP 删除任何已删除类别或子类别中包含的所有文章?

【问题讨论】:

【参考方案1】:

事情不再与 2.x 中的相同,这应该不足为奇,因为基本上整个 ORM 层已被替换。

这里发生的是,当Model.beforeDelete 事件被调度时,树行为将删除类别的子节点。这发生在任何关联删除操作运行之前,出于性能原因,它使用单个 DELETE 查询完成,不会触发任何回调。

因此,当任何关联删除操作运行时,已经没有类别 C,因为它已经因为是类别 B 的子节点而被删除。

有多种处理方式,例如,您可以在数据库中创建适当的外键约束来删除链接的文章记录(这当然会绕过任何应用程序级别的删除功能),或者设置外键到NULL,然后运行第二个删除操作来删除孤立的文章,然后您可以决定是在没有回调的单个删除查询中执行此操作,还是逐个删除文章实体。

当然还有更多的方法,但我认为不会有更漂亮的方法,例如你可以先获取所有子节点,然后禁用树行为,将所有类别实体一个一个删除,以便级联关联删除操作确实运行,然后再次启用树行为,最后恢复树......非常丑陋,可能是性能杀手,不推荐,我什至不应该提到它!

当然,您也可以在 GitHub 上针对允许可选逐个删除树子节点以触发回调的功能请求创建问题。对于小树,这可能是一个可行的选择。

【讨论】:

以上是关于在 hasMany 中依赖 true 不能在 cakephp4 中的子节点上工作的主要内容,如果未能解决你的问题,请参考以下文章

Ember.js:重新加载通过有效负载中的“链接”给出的 .hasMany 关系

具有嵌套 hasMany 或 belongsTo 关系的 Ember 模型

CakePHP - 在模型中查找没有 hasMany 关系的 hasMany 关联?

CA 证书没有作为 true 的 basicConstraints 扩展

如何在孩子中使用hasMany,其中有belongsTo

Azure Key Vault 证书 - 创建基本约束 CA:True