CakePHP表单上的多个复选框(HABTM)的验证问题

时间:2012-05-10 07:27:42

标签: cakephp

简短版

我在表单上有一些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发布)后,我将我的Request模型设置为:

<?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没有在<div>上设置“错误”类,也没有按原样创建<div class="error-message">Please select 1</div>

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

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

1 个答案:

答案 0 :(得分:0)

我在这里发帖,因为这实际上比你找到的the related question要好得多。

我正在撞墙,试图处理同样的问题,即在页面中显示验证错误。我正在使用CakePHP v1.2,但我遇到了类似的问题,尽管我实际上已将HABTM拆分为各个表,即Request->BrochuesRequest->Brochure。这是因为我无法随意删除和重新添加连接表行。

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

第二个问题实际上是显示的错误消息低至调用$field时使用的invalidate值。多年来我一直在包括模型和字段,假设这与输入的无效调用相匹配,即你有$form->input('BrochuresRequest.brochures_id')所以你需要$this->BrochuresRequest->invalidate('BrochuresRequest.brochures_id')

然而,错误,您只需要$this->BrochuresRequest->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->data被传递的问题。
  4. 如果您希望beforeValidate阻止任何保存操作,则{{1}}应返回false。