CakePHP - 在 Model->beforeSave() 中从插入更改为更新



这是我的beforeSave函数。checkExisting()检查$this->data中的某些字段是否唯一,如果没有现有记录,则返回false;如果存在,则返回现有记录的ID。此函数运行正常。

    public function beforeSave(){
    if ($this->checkExisting() !== false){
        $this->id = $this->checkExisting();
    }
    return true;
}

我认为我的代码应该这样做:如果有一个现有的记录,将Model->id设置为该现有记录的id,从而强制CakePHP更新而不是插入。

这段代码实际做的是插入一条新记录,无论如何

$this->id = $this->checkExisting();对于$this->data['Model']['id'] = $this->checkExisting();, MySQL给出一个错误(主键的值重复),因为Cake仍然试图插入数据,而不是更新数据。

在哪个阶段Cake决定执行插入而不是更新?beforeSave()影响这个决定是否太晚了?

编辑-这是我的控制器代码:
public function add(){
    if (!empty($this->data)){
        $saved = 0;
        foreach($this->data['Attendance'] as $att){
            $this->Attendance->create();
            if ($this->Attendance->save(array('Attendance'=>$att))){
                $saved++;
            }
            if ($saved > 0){
                $this->Session->setFlash('Data saved successfully','success');
            }else{
                $this->Session->setFlash('No data was saved.  Please make sure you have entered some data.','failure');
            }
        }
    }
}

考虑一下,这是否与我显式调用考勤::create()有关?

不,beforeSave现在更改还不算太晚。Model->save()按顺序执行以下操作:

  1. 调用Model->set(),传递提供的数据。提取一个id并设置Model->id
  2. 调用回调函数(包括beforeSave())
  3. 根据设置的Model->id决定是更新还是插入

假设checkExisting()行为正确,上面的代码应该可以工作。我想再检查一下你的checkExisting()代码。

还请注意,您的代码在两次调用checkExisting()时效率低下。这样会更好:

$existing = $this->checkExisting();
if($existing) {
    $this->id = $existing;
}

编辑我猜您已经创建了checkExisting(),因为如果其中一条记录无效,上面的add()操作最终会保存部分记录集。您应该使用saveAll(),它可以在保存任何记录之前验证所有记录。

public function add() {
    if(!empty($this->data)) {
        if($this->Attendance->saveAll($this->data)) {
            $this->Session->setFlash('Data saved successfully','success');
        } else {
            $this->Session->setFlash('No data was saved.  Please make sure you have entered some data.','failure');
        }
    }
}

如果你的代码或Tyler的代码工作,那一定是某种奇迹。当调用beforeSave时,Cake已经进行了查询,以知道记录集是否存在,并且需要更新或插入。你无法在beforeSave中更改为Update。一个可能的解决方案是删除存在的记录集:

public function beforeSave() {
    $existing = $this->checkExisting();
    if($existing) {
        $this->id = $existing;
        $this->delete();
    }
    return true;
}

是否允许用户在不需要ID的情况下提交表单?通常,如果用户正在编辑一条记录,您应该已经有了ID,并且在提交表单时不需要检查它。然后,控制器中的函数将提交带有ID的记录,告诉模型它是UPDATE而不是SAVE。

听起来你可能在代码的某个地方走了捷径。你会发布你的控制器函数做保存/更新。然后我们可以提供正确的帮助。

最新更新