【问题标题】:Validation problems with multiple checkboxes (HABTM) on CakePHP formCakePHP 表单上的多个复选框 (HABTM) 的验证问题
【发布时间】:2012-05-10 07:27:42
【问题描述】:

短版

我在表单上有一些 HABTM 复选框。验证工作正常(至少需要检查一个复选框才能通过验证),但没有按应有的方式生成 CakePHP 错误消息 div。

加长版

我有一个允许用户填写他们的姓名和电子邮件地址,然后从他们希望收到的小册子(复选框)列表中选择。

表格如下所示:

<?php
echo $this->Form->create('Request',array('action' => 'index'));
echo $this->Form->input('id');
echo $this->Form->input('name');
echo $this->Form->input('email');
echo $this->Form->input('Brochure',array(
        'label' => __('Information Required:',true),
        'type' => 'select',
        'multiple' => 'checkbox',
        'options' => $list,
        'selected' => $this->Html->value('Brochure.Brochure'),
));
echo $this->Form->submit('Submit');
echo $this->Form->end();
?>

在我的控制器中,$list 设置如下:

$this->Request->Brochure->find('list',array('fields'=>array('id','name')));

在阅读 Stack Overflow 上 HABTM form validation in CakePHP 中的第二个答案(由 user448164 发布)后,我将我的请求模型设置如下:

<?php

class Request extends AppModel {

var $name = 'Request';

function beforeValidate() {
    foreach($this->hasAndBelongsToMany as $k=>$v) {
        if(isset($this->data[$k][$k]))
        {
            $this->data[$this->alias][$k] = $this->data[$k][$k];
        }
    }
}

var $validate = array(
    'name' => array(
        'rule' => 'notEmpty',
        'message' => 'Please enter your full name'
    ),
    'email' => array(
        'rule' => 'email',
        'message' => 'Please enter a valid email address'
    ),
    'Brochure' => array(
        'rule' => array('multiple', array('min' => 1)),
        'message' => 'Please select 1'
    ),
);
?>

这实际上可以正常工作 99%。如果未选中任何复选框,则验证将失败。但是,唯一的问题是 Cake 没有在 &lt;div&gt; 上设置“错误”类,也没有按照应有的方式创建 &lt;div class="error-message"&gt;Please select 1&lt;/div&gt;

对于姓名和电子邮件,没有问题 - 错误 div 正在正确创建。

因此,澄清一下,验证适用于我的 HABTM 复选框。唯一的问题是没有生成错误 div。

【问题讨论】:

  • 什么蛋糕版本,$this-&gt;validationErrors 长什么样子?
  • @jeremyharris 我使用的是 Cake 2.1.1,但实际上自从 Cake 1.3.x 以来我就遇到了这个问题。 $this-&gt;validationErrors 为空,但 $this-&gt;Request-&gt;validationErrors 为我提供了包含我在模型中设置的“请选择 1”错误消息的数组。
  • 是的,但是验证错误数组的格式是什么?这就是 Cake 如何确定一个字段是否应该显示错误。您可能需要稍微按摩一下,这就是我要说的,就像您链接到的问题中给出的答案一样。
  • @jeremyharris 是的,你是对的,我链接到的问题中的已接受答案实际上非常有效。我之前尝试过,但它不起作用,但从那以后我做了一些模型更改,所以我猜是这样。很抱歉浪费您的时间。我已将此标记为重复问题。
  • 不浪费,不用担心。很高兴你成功了!

标签: cakephp


【解决方案1】:

我在此处发布此问题,因为这实际上是一个比您找到的the related question 更好的问题。

我正用头撞墙,试图处理使验证错误显示在页面中的相同问题。我正在使用 CakePHP v1.2 并且遇到了类似的问题,尽管我实际上已将 HABTM 拆分为单独的表,即Request-&gt;BrochuesRequest-&gt;Brochure。这是因为我不能让它随意删除和重新添加连接表行。

首先我认为accepted answer from your linked question 假设您在触发beforeValidate 调用时正在执行save / saveAll,但是我是通过validates 调用来执行此操作的。不同之处在于您需要先调用Request-&gt;set 方法。 Jonathan Snook 在Multiple Validation Sets 上的一篇文章指出了这个问题。

第二个问题实际上是让错误消息出现在您调用invalidate 时使用的$field 值。多年来,我一直在包括模型和字段,假设这就是它与输入的无效调用匹配的方式,即你有$form-&gt;input('BrochuresRequest.brochures_id'),所以你需要$this-&gt;BrochuresRequest-&gt;invalidate('BrochuresRequest.brochures_id')

但是那错误你只需要$this-&gt;BrochuresRequest-&gt;invalidate('brochures_id')

<?php   
// requests/add view
echo $form->input('BrochuresRequest.brochures_id', array('multiple' => true));

// requests_controller
function add() {
    if (!empty($this->data)) {
        $this->Request->create();
        // critical set to have $this->data 
        // for beforeValidate when calling validates
        $this->Request->set($this->data); 
        if ($this->Request->validates()) {
            $this->Request->saveAll($this->data);
        }
    }
}

// request model
function beforeValidate() {
    if (count($this->data['BrochuresRequest']['brochures_id']) < 1) {
        $this->invalidate('non_existent_field'); // fake validation error on Project
        // must be brochures_id and not BrochuresRequest.brochures_id
        $this->BrochuresRequest->invalidate('brochures_id', 'Please select 1');
        return false;
    }
    return true;
}
?>

我在途中捡到的其他一些东西:

  1. 您不需要separate $form->error in the view
  2. 我一辈子都无法让“多重”验证规则在模型中起作用
  3. accepted answer 检查 isset,但我认为这不是必需的,并且掩盖了没有通过 $this-&gt;data 的问题。
  4. 如果您希望 beforeValidate 阻止任何保存操作,则应返回 false。

【讨论】:

  • 哇,这是很久以前的事了,但是代码仍在使用中,所以我有时间再回去试试你的建议。如果可行,我会回来将此标记为已接受的答案:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多