3

短縮版

フォームにいくつかの HABTM チェックボックスがあります。検証は正しく機能しています (検証に合格するには、少なくとも 1 つのチェックボックスをオンにする必要があります) が、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')));

スタック オーバーフローの CakePHP での HABTM フォーム検証の 2 番目の回答 (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 が に「エラー」クラスを設定しておらず、必要に応じ<div>て を作成し<div class="error-message">Please select 1</div>ていないことです。

名前と電子メールについては問題ありません。エラー div は適切に作成されています。

したがって、明確にするために、検証私のHABTMチェックボックスで機能しています。唯一の問題は、エラー div が生成されていないことです。

4

1 に答える 1

0

これは実際には、あなたが見つけた関連する質問よりもはるかに優れた質問であるため、ここに投稿しています。

検証エラーがページに表示されるという同じ問題を処理しようとして、壁に頭をぶつけていました。私はCakePHP v1.2を使用していますが、実際にはHABTMを個々のテーブルに分割しましたが、同様の問題に遭遇しましたRequest->BrochuesRequest->Brochure。これは、結合テーブルの行を自由に削除して再追加することができないためです。

まず、リンクされた質問から受け入れられた回答は、呼び出しがトリガーされたsave / saveAllときにあなたがやっていると仮定していると思いますが、私は呼び出しを介してそれを行っていました。違いは、最初にメソッドを呼び出す必要があることです。複数の検証セットに関するJonathan Snookの記事で、その問題が指摘されました。beforeValidatevalidatesRequest->set

2 番目の問題は、実際にエラー メッセージが表示される$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. ビューに別の $form->error は必要ありません
  2. 私は一生、「複数の」検証ルールをモデルで機能させることができませんでした
  3. 受け入れられた回答はisset をチェックしますが、これは必須ではなく$this->data、通過しないという問題を隠していると思います。
  4. beforeValidate保存アクションを防止する場合は、 false を返す必要があります。
于 2013-06-19T21:30:10.700 に答える