这是我的beforeSave功能。 checkExisting()检查$ this->数据中的某些字段是否唯一,如果没有现有记录,则返回false,如果存在,则返回现有记录的ID。这个功能工作正常。
public function beforeSave(){
if ($this->checkExisting() !== false){
$this->id = $this->checkExisting();
}
return true;
}
我认为我的代码应该做的是:如果有现有记录,请将Model-> id设置为该现有记录的ID,然后强制CakePHP更新而不是插入。
此代码实际上做的是插入新记录,无论如何。
如果我更改$ this-> id = $ this-> checkExisting(); to $ 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');
}
}
}
}
考虑一下,是否与我明确调用Attendance :: create()这一事实有关?
答案 0 :(得分:2)
不,之前保存还为时已晚。 Model-> save()按顺序执行以下操作:
上面的代码应该可以正常运行,假设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');
}
}
}
答案 1 :(得分:2)
如果您的代码或Tyler的代码有效,那么它必定是某种奇迹。当调用beforeSave时,Cake已经执行了查询以了解记录集是否存在且是否需要更新,否则为Insert。您无法在beforeSave中更改为更新。一种可能的解决方案是删除记录集(如果存在):
public function beforeSave() {
$existing = $this->checkExisting();
if($existing) {
$this->id = $existing;
$this->delete();
}
return true;
}
答案 2 :(得分:0)
您正在做的事情是否允许用户在不需要ID的情况下提交表单?通常,如果用户正在编辑记录,您应该已经拥有该ID,并且在提交表单时无需检查该ID。然后控制器中的函数将提交附有ID的记录,告诉模型它是UPDATE而不是SAVE。
听起来对你来说,你可能会在代码中的某些地方进行捷径。你会发布正在进行保存/更新的控制器功能吗?然后我们可以提供正确的帮助。