在beforeSave()和halt save()调用上,从CakePHP 3.8模型返回自定义422实体错误的正确方法是什么?
我目前正在致力于将422个http验证错误添加到基于Cake 3.8的API中 对于任务控制器,我有如下内容:在beforeSave()和halt save()调用上,从CakePHP 3.8模型返回自定义422实体错误的正确方法是什么?,php,cakephp,cakephp-3.0,Php,Cakephp,Cakephp 3.0,我目前正在致力于将422个http验证错误添加到基于Cake 3.8的API中 对于任务控制器,我有如下内容: <?php class TasksController extends AppController { public function initialize() { parent::initialize(); } public function add(string $id): void { $valid
<?php
class TasksController extends AppController
{
public function initialize()
{
parent::initialize();
}
public function add(string $id): void
{
$validationErrors = [];
$task = $this->newEntity($this->request->getData(););
if ($this->Tasks->save($task)) {
// Errors added to entity in before save will not cause
// save() to return false and stop the proccess from
// making it here
$this->response = $this->response->withStatus(200);
} else {
$validationErrors = [$task->getErrors()];
if (count($validationErrors) > 0) {
$this->response = $this->response->withStatus(422);
} else {
throw new BadRequestException("The posted entity is is invalid.");
}
}
// Render json output for success / errors
$this->set($this->createViewVars(['entity' => $task], $validationErrors));
}
}
<?php
class TasksTable extends AppTable
{
public function initialize(array $config)
{
parent::initialize($config);
}
public function beforeSave(Event $event, Entity $task, ArrayObject $options)
{
parent::beforeSave($event, $task, $options);
$task->setError('technician', 'No default technician was able to be found');
if(count($task->getErrors()) > 0) {
$event->stopPropagation();
}
}
}
beforemashall
似乎不是这样做的地方。是否有某些原因导致它无法进入正常验证(在修补实体时发生)或规则(在保存之前发生)?这两个都是为这类事情而设计的。此外,您不需要停止事件的传播;如果实体中有任何错误,则不会执行保存。@GregSchmidt查看代码时,如果需要的话,我可能会将beforemashall中的内容转换为beforeSave?这种逻辑基本上是通过站点设置进行梳理,并根据系统中的设置自动填充某些字段,因此它不是验证代码,它只是在预填充过程中揭示验证问题。有时,这些值可能来自最终用户,在这种情况下,该逻辑甚至不会运行。我想我们可以将字段留空,让它们落在验证系统上,以防没有任何内容需要预填充?我删除了问题的BeforeMarshall部分,因为它可以解决。我认为最“蛋糕式”的方法可能是使用beforeSave
来填充字段,然后让规则检查这些值是否有效。@GregSchmidt这当然是一个选项,但如果禁用了checkRules
,则不会触发该事件。我想说,您的第一直觉是,数据操作应该在marshall()之前进入
,这是正确的,至少就请求数据而言是正确的。进一步操作有效实体和手动中止保存过程应进入beforeSave()
。我不确定显示的代码有什么问题,即使它不会导致返回false
,但返回null
(使用$event->setResult(false)
或return false
),它仍然应该中止保存过程并进入else
分支。