CakePHP 3 belongsToMany 验证

CakePHP 3 belongsToMany Validation

我正在为如何使用 belongsToMany 关系进行验证而苦恼。即 classic recipes/ingredients 关系。我希望食谱在创建或编辑时始终包含一种成分。我的 RecipesTable 中的验证会是什么样子?我试过:

$validator->requirePresence('ingredients')->notEmpty('ingredients')

以及

$validator->requirePresence('ingredients._ids')->notEmpty('ingredients._ids')

第二个有效,因为我的表单未通过验证,但它不会将 error class 添加到输入中。我正在设置字段名称为 ingredients._ids.

的输入

我在创建要传递给 $this->post 的数据时也遇到了问题,以便在我的测试中成功添加记录。我的测试数据如下:

$data = [
    'ingredients' => [
        '_ids' => [
             '2'
        ]
    ];

当然,我在测试中使用 $this->post('/recipes/add', $data);

post

我在测试中没有通过所需的成分规则。

我解决了如何设置验证器的问题。在配方 Table 验证器中:

$validator->add('ingredients', 'custom', [
    'rule' => function($value, $context) {
        return (!empty($value['_ids']) && is_array($value['_ids']));
    },
    'message' => 'Please choose at least one ingredient'
]);

但是,验证消息没有显示在表单上,​​所以我正在做一个 isFieldError 检查:

        <?php if ($this->Form->isFieldError('ingredients')): ?>
            <?php echo $this->Form->error('ingredients'); ?>
        <?php endif; ?>

我在我的视图文件中使用多个复选框而不是多个select。

然后,我在表单上收到了验证消息。

正如我所想,一旦我弄清楚了验证器,我的测试就到位了。我上面显示的确实是正确的,可以在测试中传递数据。

我希望将此答案添加为 Kris 答案的评论,但我没有足够的声誉。

或者,要解决表单上未显示验证消息的问题,您可以在控制器中添加这两行。

if(empty($this->request->data['ingredients']['_ids']))
    $yourentity->errors('ingredients', 'Please choose at least one ingredient');