CakePHP-在模型中从插入更改为更新->;beforeSave()

CakePHP-在模型中从插入更改为更新->;beforeSave(),cakephp,cakephp-1.3,Cakephp,Cakephp 1.3,这是我的beforeSave函数。checkExisting()检查$this->data中的某些字段是否唯一,如果没有现有记录,则返回false;如果现有记录存在,则返回现有记录的ID。此功能工作正常 public function beforeSave(){ if ($this->checkExisting() !== false){ $this->id = $this->checkExisting(); } return t

这是我的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');
            }
        }
    }
}

仔细想想,这是否与我显式调用Attention::create()有关?

您正在做的事情是否允许用户在不需要ID的情况下提交表单?通常,如果用户正在编辑记录,则您应该已经拥有该ID,并且在提交表单时不需要检查该ID。然后控制器中的函数将提交附加ID的记录,告诉模型这是一个更新而不是保存


在我看来,你可能在代码的某个地方走捷径。是否发布正在执行保存/更新的控制器功能。然后,我们可以提供正确的帮助。

不,在保存之前更改此设置还不算太晚。Model->save()按顺序执行以下操作:

  • 调用Model->set(),传递提供的数据。这将提取一个id并设置模型->id
  • 调用回调函数(包括beforeSave())
  • 根据设置的模型->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');
            }
        }
    }
    

    如果你的代码或泰勒的代码起作用,那一定是某种奇迹。调用beforeSave时,Cake已执行查询以了解记录集是否存在,是否需要更新或插入。无法在beforeSave中更改为更新。一种可能的解决方案是删除记录集(如果存在):

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

    谢谢,我已经三次检查了checkExisting()函数,它正常工作,返回false或记录的ID。请参阅Cakephp 2.0.5中的“我的编辑”了解更多代码exists()回调,以确定它是否是在订单的早期发生的更新或插入。覆盖模型中的exists()。与add_file类似,查看文件allready的md5_file()是否在数据库中,并且是否以重复文件结束。