初心者で恐縮ですがよろしくお願いします。
モデルを使用しないフォームで受け取った、ネストした値をバリデーションしたいのですが、うまくいきません。
こちらを参考にしています。
Form https://book.cakephp.org/3.0/ja/views/helpers/form.html
バリデーション https://book.cakephp.org/3.0/ja/core-libraries/validation.html
モデルのないフォーム https://book.cakephp.org/3.0/ja/core-libraries/form.html
テストとしてモデルのないフォームのコード↓をそのままコピーし、
//コントローラ namespace App\Controller; use App\Controller\AppController; use App\Form\ContactForm; class ContactController extends AppController { public function index() { $contact = new ContactForm(); if ($this->request->is('post')) { if ($contact->execute($this->request->getData())) { $this->Flash->success('すぐにご連絡いたします。'); } else { $this->Flash->error('フォーム送信に問題がありました。'); } } $this->set('contact', $contact); } } --------------------------------- // src/Form/ContactForm.php の中で namespace App\Form; use Cake\Form\Form; use Cake\Form\Schema; use Cake\Validation\Validator; class ContactForm extends Form { protected function _buildSchema(Schema $schema) { return $schema->addField('name', 'string') ->addField('email', ['type' => 'string']) ->addField('body', ['type' => 'text']); } protected function _buildValidator(Validator $validator) { return $validator->add('name', 'length', [ 'rule' => ['minLength', 10], 'message' => '名前は必須です' ])->add('email', 'format', [ 'rule' => 'email', 'message' => '有効なメールアドレスが要求されます', ]); } protected function _execute(array $data) { // メールを送信する return true; } } //index.ctp echo $this->Form->create($contact); echo $this->Form->control('name'); echo $this->Form->control('email'); echo $this->Form->control('body'); echo $this->Form->button('Submit'); echo $this->Form->end();
バリデーションのページの「バリデータをネストする」の項目にある↓のコードを参考にして、
$validator = new Validator(); $validator->add('title', 'not-blank', ['rule' => 'notBlank']); $commentValidator = new Validator(); $commentValidator->add('comment', 'not-blank', ['rule' => 'notBlank']); // ネストされたバリデータをつなげる $validator->addNestedMany('comments', $commentValidator); // ネストされたバリデータからのエラーを含むすべてのエラーを取得する $validator->errors($data);
_buildValidatorの部分を以下のように書き換えました。
protected function _buildValidator(Validator $validator) { $nested_data = $validator; $nested_data->add('name', 'length', [ 'rule' => ['minLength', 10], 'message' => '名前は必須です' ])->add('email', 'format', [ 'rule' => 'email', 'message' => '有効なメールアドレスが要求されます', ]); return $validator->addNestedMany('a', $nested_data); }
テンプレートは以下のようになっています。
<?=$this->Form->create($mytest) ?> <?=$this->Form->control('a.name') ?> <?=$this->Form->control('a.email') ?> <?=$this->Form->control('a.body') ?> <?=$this->Form->button('Submit') ?> <?=$this->Form->end() ?>
これでフォームに値を書いて送信するとメールアドレスに@が抜けたときのみjavascriptによる注意が出ますが、他は、不正な場合は正しいエラーコメントが出ず、正しい場合はバリデーションチェックが常にfalseとなった状態です。
Formクラスに__debugInfoというメソッドがあったので出してみました。
[ '_schema' => [ '_fields' => [ 'name' => [ 'type' => 'string', 'length' => null, 'precision' => null ], 'email' => [ 'type' => 'string', 'length' => null, 'precision' => null ], 'body' => [ 'type' => 'text', 'length' => null, 'precision' => null ] ] ], '_errors' => [ 'a' => [ '_nested' => 'The provided value is invalid' ] ], '_validator' => [ '_presenceMessages' => [], '_allowEmptyMessages' => [], '_useI18n' => true, '_providers' => [ (int) 0 => 'default' ], '_fields' => [ 'name' => [ 'isPresenceRequired' => false, 'isEmptyAllowed' => false, 'rules' => [ (int) 0 => 'length' ] ], 'email' => [ 'isPresenceRequired' => false, 'isEmptyAllowed' => false, 'rules' => [ (int) 0 => 'format' ] ], 'a' => [ 'isPresenceRequired' => false, 'isEmptyAllowed' => false, 'rules' => [ (int) 0 => '_nested' ] ] ] ] ]
モデルを使用しない場合formクラスを継承してコントローラ名+Formクラスを作ると思いますが、その場合でもネストされた値の検証は可能でしょうか?
よろしくお願いします。
回答1件
あなたの回答
tips
プレビュー