使用DataObjectManager调用两次onAfterWrite方法

时间:2012-08-24 14:12:53

标签: silverstripe

我正在使用dataobjectmanager与owner_many之间的关系(我不能使用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();
}

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

由于

1 个答案:

答案 0 :(得分: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开箱即用地处理这类内容,您可能会发现在此基础上构建应用程序更容易。