CakePhp::在创建/插入查询时缺少字段

CakePhp::在创建/插入查询时缺少字段,php,cakephp,constraints,cakephp-2.3,Php,Cakephp,Constraints,Cakephp 2.3,我是CakePhp新手,目前正在尝试使用票证、事件、任务、用户等实现一个简单的票证系统。在基本CRUD功能下,状态已通过ajax调用标记为“完成”的记录单应生成一个新记录单(表示工作流中的下一步) 但是,通过ajax在Ticket::afterSave()中创建下一个Ticket作为对$this->saveField()的回调,最终失败,违反了完整性约束,而“普通烘焙的”edit()调用则有效。 Cake似乎只是忽略了所生成代码中$this->save()上的一些要保存的字段 MySQL INS

我是CakePhp新手,目前正在尝试使用票证、事件、任务、用户等实现一个简单的票证系统。在基本CRUD功能下,状态已通过ajax调用标记为“完成”的记录单应生成一个新记录单(表示工作流中的下一步)

但是,通过ajax在
Ticket::afterSave()
中创建下一个Ticket作为对
$this->saveField()
的回调,最终失败,违反了完整性约束,而“普通烘焙的”
edit()
调用则有效。 Cake似乎只是忽略了所生成代码中
$this->save()
上的一些要保存的字段 MySQL INSERT INTO语句,我想不出解释

这里是票证的模型

<? class Ticket extends AppModel {

    // [...]

    public function update($status) {

        return $this->saveField('status', $status);
    }

    public function afterSave($created, $options = array()) {

        //[...] if ticket state was changed to done:

        // generate data for Ticket with next Task in Workflow
        $this->Event->id = $this->field('event_id'); 
        $ticketData = $this->Event->generateNext();

        // check if data is correct
        debug($ticketData);

        // create new ticket
        $this->create();

        return $this->save($ticketData);

    }
}
但是,当ajax调用
update
函数时,创建失败,原因是:

Error: [...] Integrity constraint violation: Cannot add or update a child row: a foreign key constraint fails (`table`.`tickets`, CONSTRAINT `fk_tickets_users1` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) [...])
…显示SQL查询:

'INSERT INTO `table`.`tickets` (`status`, `modified`, `created`) VALUES ('Requested', '2014-02-05 22:00:32', '2014-02-05 22:00:32')'
如您所见,生成的查询完全遗漏了
user\u id
an等的字段,这当然会导致创建失败。但调试证明了他们的存在?!令人困惑 在烘焙的
edit
函数中调用
Ticket::save()
时,查询结果如下:

'INSERT INTO `table`.`tickets` (`status`, `event_id`, `task_id`, `user_id`, `modified`, `created`) VALUES ('Requested', 11720, 9, 1, '2014-02-05 20:34:25', '2014-02-05 20:34:25')'
我想我可以通过使用像
Ticket->query()
这样的自定义查询来避免这种行为?但我更愿意理解不同的结果,并以“蛋糕式”的方式来做。 我希望这在某种程度上是可以理解的,并且非常感谢任何帮助


非常非常感谢

由于在初始更新状态字段后,您将从Ticket本身的afterSave()方法中创建新的Ticket,因此模型的白名单将设置为初始保存的唯一字段(status)。 所有其他字段将被丢弃

$this->save($ticketData);
改为:

$this->save($ticketData, false, array(
    'event_id',
    'task_id',
    'user_id',
    'status'
);

注意对afterSave()的递归调用。上述调用$this->afterSave()将再次调用afterSave()本身。

非常感谢,savedario!你的解决方案很有魅力。突然间,我的困惑感觉真的很愚蠢。。我马上就去查蛋糕的白名单。同样感谢您提到递归调用,我认为只要下一个票据没有标记为“完成”,它就应该可以了。不客气。就在几个小时前,我无意中发现了这一点。
$this->save($ticketData, false, array(
    'event_id',
    'task_id',
    'user_id',
    'status'
);