0

我在车主和汽车之间使用具有 many_many 关系的 dataobjectmanager(我不能为此使用 manymanydataobjectmanager)。每当创建新车时,我都会遍历所有者的所有实例并将其 ID 与新车 ID 一起添加到链接表中。

我的问题是执行此操作的代码在 onafterwrite 方法中并被调用两次。我不确定为什么。我还注意到,对于我的三个所有者来说,它奇怪地在链接表中创建了行。前两个 ID 将按顺序排列,然后将粘贴一个。所以它将是第 1 行、第 2 行和第 4 行,没有第 3 行。

这是我的 onAfterWrite 方法

public function onAfterWrite() {

    if(Permission::check('ADMIN')){
        $Pages = DataObject::get('Owner');              

        foreach($Pages as $owner) {

        DB::query("INSERT INTO Owner_Cars (OwnerID, CarID) VALUES ('". $owner->ID . "', '" . $this->ID . "')");
        }
    }
    else {
        echo "Failure";
        return false;
    }
    return parent::onAfterWrite();
}

我很感激你能给我的任何建议。

谢谢

4

1 回答 1

3

onAfterWrite()方法可能被调用两次,因为write()被调用了两次。发生这种情况的最常见原因是:

  • 一个 write() 恰好生成了 ID
  • 然后另一个 write() 作为保存依赖于该 ID 的相关记录的一部分发生。

一般来说,我认为你不能依赖 onAfterWrite() 被调用一次: write() 应该被设计成可以被调用任何旧的次数,并且只有在发生更改时才会真正影响数据库做出来。

您需要让您的代码调用必要的 DELETE、INSERT 和/或 UPDATE 语句才能与此兼容。例如,您可能会:

  • 选择所有 Owner_Cars 记录,其中 OwnerID = $owner->ID
  • 删除任何不在 $Pages 列表中的内容
  • 插入 $Page 列表中尚未在 Owner_Cars 中的任何内容

如果可以的话,我会提出的另一个建议是试用 SilverStripe 3。SilverStripe 3 的 GridField 开箱即用地处理这类事情,您可能会发现在此基础上构建您的应用程序更容易。

于 2012-10-14T23:14:31.080 回答