【问题标题】:CakePHP deleteAll for many to many relationship does not remove join records多对多关系的 CakePHP deleteAll 不会删除连接记录
【发布时间】:2016-08-12 00:45:34
【问题描述】:

我正在使用带有 Postgres 9.4 的 CakePHP v3.17

我也在尝试让$this->SomeTable->deleteAll([...]) 删除连接表中的记录。

Stops 的表和Routes 的表对总线系统进行映像。停靠点与许多路线相关联(因为多条公交路线可以停靠在每条路线上),并且路线显然与许多停靠点相关联。

RoutesTable.php:

$this->belongsToMany('Stops');

StopsTable.php:

$this->belongsToMany('Routes');

这是我想使用的删除逻辑,但由于连接表中的记录被留下,所以不起作用:

    $stopsTable = TableRegistry::get('Stops');
    $stopsTable->deleteAll(['agency_id' => $agency->id]);

    $routesTable = TableRegistry::get('Routes');
    $routesTable->deleteAll(['agency_id' => $agency->id]);

以下是可以正常工作的逻辑,但效率低下,因为它必须遍历每个停靠点:

    $stopsTable = TableRegistry::get('Stops');
    foreach ($agency->stops as $stop) {
        $stopsTable->delete($stop);
    }
    $routesTable = TableRegistry::get('Routes');
    $routesTable->deleteAll(['agency_id' => $agency->id]);

有什么更好/正确的方法来做到这一点?

这里是similar question,但对于 v2.x,这里不一定相关。

【问题讨论】:

  • CakePHP 核心中是否有涵盖您的案例并确保删除连接表记录的单元测试?如果不是,请在 Github 上将其报告为问题。你确定只剩下连接表记录而不是连接表记录吗?尝试为您的 assoc 设置 'dependent' => true,,我不确定它现在是否默认为 true。
  • 嗨@burzum 我已经用依赖=> true 试过了,是的,我确定只剩下连接表记录,因为我正在对空表进行测试......所以测试后 Stops 和 Routes 是空的,但 routes_stops 仍然是满的。我不确定单元测试问题...
  • 您可能需要启用cascading deletes 而不仅仅是依赖。
  • 我认为批量删除不适用于级联删除,因为之前和之后的事件不会应用于批量删除。文档说您需要单独加载记录并删除它们。
  • @chrisShick 你能分享一个链接到文档所说的地方吗?

标签: php postgresql cakephp cakephp-3.x cakephp-3.1


【解决方案1】:

没有办法做你需要的。但是,我当然会建议按照您在开篇文章中已经说过的操作并将其包装在事务中(请注意,这是未经测试的,但应该可以):

$stopsTable->connection()->transactional(function () use ($stopsTable, $stops) {
    foreach ($stops as $stop) {
        $stopsTable->delete($stop);
    }
});

【讨论】:

  • 谢谢。您确定->transactional() 是必要的吗?我看到in the docs 说“所有删除都发生在一个事务中”,但不确定这是什么意思。
  • 文档意味着被删除的主要对象及其依赖关联都在事务中被删除。
猜你喜欢
  • 2013-04-05
  • 1970-01-01
  • 2014-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-01
  • 1970-01-01
相关资源
最近更新 更多