如何在CakePHP中验证所需的关联存在?

prdp8dxp  于 2022-11-12  发布在  PHP
关注(0)|答案(1)|浏览(135)

我的Proyectos和Medios模型之间有一个工作中的belongsToMany关联。如果我添加了一个新的Proyecto实体,我可以从注册的Medios中进行选择,并且所有内容都被充分保存。问题是,无论我是否选择任何Medio,实体都被正确保存,并且我希望它成为表单中的必填字段。
我尝试在表单中添加“required =〉true”,并在ProyectoTable中添加“$validator-〉notEmpty”,但是没有效果(即使没有选择Medio,它仍然保存表单)。
我一直在阅读CakePHP 3.x文档,但是我一直没有找到正确的方法来验证关联数据的存在。我遗漏了什么?(我想我应该添加某种特殊的规则,但是我不知道如何以及在哪里放置它。
我的模型:

class ProyectosTable extends Table
{
    public function initialize(array $config)
    {
        parent::initialize($config);

        [...]

        $this->belongsToMany('Medios', [
            'foreignKey' => 'proyecto_id',
            'targetForeignKey' => 'medio_id',
            'joinTable' => 'medios_proyectos',
        ]);
    }

    public function validationDefault(Validator $validator)
    {
        [...]

            $validator
            ->requirePresence('medios', 'create')
            ->notEmpty('medios');

        return $validator;
    }
}

我的控制器:

public function add()
{
    $proyecto = $this->Proyectos->newEntity();
    if ($this->request->is('post')) {
        $partida = $this->Proyectos->patchEntity($proyecto, $this->request->getData());
        if ($this->Proyectos->save($proyecto)) {
            $this->Flash->success('El proyecto ha sido salvado.');

            return $this->redirect(['action' => 'index']);
        }
        $this->Flash->error('El proyecto no pudo ser salvado.');
    }

    $medios = $this->Proyectos->Medios->find('list', ['limit' => 200]);
    $this->set(compact('proyecto','medios'));
}

我的检视:

<?= $this->Form->create($proyecto) ?>
    [...]
    <?= $this->Form->control('medios._ids', ['options' => $medios,'required' => true]); ?>
    [...]
    <?= $this->Form->button('submit') ?>
<?= $this->Form->end() ?>

我已经试过将它更改为“$validator-〉requirePresence('medios._ids','create')-〉notEmpty('medios._ids');“,但无论我选择一个、全部还是根本不选择Medio,视图都会向我抛出“无法保存,必填字段”错误。

vhipe2zx

vhipe2zx1#

多重选择控件确实有一个隐藏的回退,如下所示:

<input type="hidden" name="medios[_ids]" value=""/>

因此,当没有选择任何内容时,该字段仍然存在,表示选择为空。使用._ids创建嵌套结构,因此为medios提交的值永远不会被解释为空,您将收到如下所示的内容:

[
    'medios' => [
        '_ids' => ''
    ]
]

所以notEmpty规则当然不会在这里应用。而且验证规则字段名不支持点语法,它们严格Map到第一级字段。
例如,你可以对medios字段使用嵌套的验证器,该验证器的规则将应用于嵌套在medios下的字段。

public function validationDefault(Validator $validator)
{
    // ...

    $validator
        ->requirePresence('medios', 'create')
        ->addNested('medios', $this->getValidator('medios'));

    return $validator;
}

public function validationMedios(Validator $validator)
{
    $validator
        ->requirePresence('_ids')
        ->notEmpty('_ids');

    return $validator;
}

另请参阅

*操作手册〉验证〉嵌套验证器
*Cookbook〉数据库访问和ORM〉验证数据〉从表中获取验证器

相关问题