【问题标题】:How to validate required association presence in CakePHP?如何在 CakePHP 中验证所需的关联存在?
【发布时间】:2021-03-08 15:37:05
【问题描述】:

我的 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,视图都会向我抛出“无法保存,必填字段”错误。

【问题讨论】:

    标签: cakephp cakephp-3.8


    【解决方案1】:

    多选控件确实有这样的隐藏后备:

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

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

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

    所以notEmpty 规则当然不适用于这里。此外,验证规则字段名称不支持点语法,它们严格映射到一级字段。

    例如,您可以对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;
    }
    

    另见

    【讨论】:

    • 太棒了!效果很好! ♥ 我知道它必须是这样的,但我不知道嵌套验证器。但是,我注意到其他一些东西,我觉得它可能与此有关......现在,如果我不选择任何选项,它会告诉我必填字段,如果我选择其中一个或多个,它会保存实体正好。但是当我尝试编辑实体时,在视图中没有选择任何选项(所以它没有加载关联),我必须重新输入它们,否则我仍然得到“字段不应该为空”。我错过了什么?
    • @DamiánFraustro 很难在没有看到代码的情况下判断,但是传递给表单的实体上不存在相关数据,这当然是一个可能的原因。
    • 哦!当然!谢谢!我没有在控制器的编辑操作中添加“包含”。当然没有相关数据被传递!现在一切正常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    • 2011-08-07
    相关资源
    最近更新 更多