質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

Q&A

解決済

1回答

4711閲覧

モデルレスフォーム ネストしたデータのバリデーション

navca

総合スコア44

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

0グッド

0クリップ

投稿2017/06/14 08:40

初心者で恐縮ですがよろしくお願いします。
モデルを使用しないフォームで受け取った、ネストした値をバリデーションしたいのですが、うまくいきません。

こちらを参考にしています。
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クラスを作ると思いますが、その場合でもネストされた値の検証は可能でしょうか?
よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

popobot

2017/06/14 10:14

addNestedManyではなくaddNestedを使ってもだめですか?
navca

2017/06/14 10:28

回答ありがとうございます。できました。バリデーションのページにある「addNestedMany() を用いることで 1:N の関係を築くことができます。」からも複数のフィールド名がある場合はmanyを使うものだと思い込んでいたのですが、addNestedとNestedMayの違いが判りません。よろしければ教えていただけないでしょうか。
guest

回答1

0

ベストアンサー

ネストしたデータがa.nameのように1:1の関係の場合、addNestedManyではなくaddNestedです。

なお、addNestedManyは、1:Nの関係の場合に使用するものなので、以下のようなフォームの場合に使うものだと思います。

php

1<?=$this->Form->create($mytest) ?> 2<?=$this->Form->control('a.0.name') ?> 3<?=$this->Form->control('a.0.email') ?> 4<?=$this->Form->control('a.0.body') ?> 5<?=$this->Form->control('a.1.name') ?> 6<?=$this->Form->control('a.1.email') ?> 7<?=$this->Form->control('a.1.body') ?> 8<?=$this->Form->button('Submit') ?> 9<?=$this->Form->end() ?>

※実際に試したことはありません...

投稿2017/06/14 20:14

編集2017/06/15 00:11
popobot

総合スコア6586

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

navca

2017/06/15 13:51

ありがとうございざいました。助かりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問