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

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

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

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

Q&A

解決済

1回答

6877閲覧

チェックボックスのバリデーションが出来ない

smnsmn

総合スコア175

CakePHP

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

0グッド

0クリップ

投稿2016/02/23 16:55

規約に同意のようなチェックボックスのバリデーションを作っているのですが、エラーメッセージが表示されません。
これ以外のバリデーションはちゃんと表示されます。

HTML

1<!--フォーム--> 2<?php echo $this->Form->create('Hoge', array('type'=>'file', 'div'=>false, 'id'=>false)); ?> 3<div class="check_agreebox"> 4<?php echo $this->Form->input('agree', array('type'=>'checkbox', 'value'=>'agree', 'div'=>false, 'id'=>'agree', 'label'=>'同意', 'class'=>false, 'required'=>false, 'error'=>false)); ?> 5<span class="error"><?php echo $this->Form->error('Hoge.agree'); ?></span> 6</div> 789<?php echo $this->Form->end(); ?>

PHP

1//Model 2 public $validate = array( 3 'agree' => array( 4 'custom_agree' => array( 5 'rule' => array('custom_agree'), 6 'message' => '同意してください。', 7 //'required' => true, 8 ), 9 ); 10 11 //オリジナルバリデーション 12 function custom_agree($num) { 13 foreach ($num as $value) { 14 if ($value == 'agree') { 15 return true; 16 } else { 17 return false; 18 } 19 } 20 } 21

ルールとしてequalTocomparison等も使ってみましたがダメでした。
なのでオリジナルのルールを作りましたがやはりダメでした。

'required' => trueを加えるとエラーメッセージが表示されますが、チェックしてもしなくても表示されます。

原因と思われるものがわかりましたらご教授頂きたいです。
チェックボックスで自動生成されるhiddenフィールドなどは関係無いですよね。

どうぞ宜しくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

Modelのコードが()の数が違うのでエラーになりましたが、次の行を削除したらそのままのコードで正常に動作しました。

PHP

1// Hoge.php 2'custom_agree' => array(

Controller側のバリデートの呼び出し部分も確認してみてください。
確認に使ったController側のコードは↓です。

PHP

1public function index(){ 2 if($this->request->is('post')){ 3 $this->Hoge->set($this->request->data); 4 if($this->Hoge->validates()){ 5 // 正常 6 }else{ 7 // バリデートエラー 8 } 9 } 10}

2016/02/24 一例追記

PHP

1function register(){ 2 if($this->request->is('post')){ 3 $this->Hoge->set($this->request->data); 4 if($this->Hoge->validates()){ 5 // ポストされた情報を整理して保存する処理 6 $name = $this->request->data['Hoge']['first_name'].' '.$this->request->data['Hoge']['last_name']; 7 $address = $this->request->data['Hoge']['prefecture'].' '.$this->request->data['Hoge']['city']; 8 $save = array('Hoge' => array( 'name' => $name 9 , 'address' => $address 10 , 'category_id' => $this->request->data['Hoge']['category_id'] 11 , 'email' => $this->request->data['Hoge']['email'] 12 , 'is_delete' => false)); 13 if($this->Hoge->save($save)){ // 敢えてもう一度バリデートは実行する 14 // 正常に保存出来たのでindexへ 15 $this->redirect(array('action' => 'index')); 16 }else{ 17 // ユーザー入力ままのバリデートには成功しているのに保存出来なかった 18 // 恐らくバリデート後の情報整理のロジックに不備があったんだろう 19 // first_name,last_nameの文字数制限はOKだけど、nameの文字数は超過したとか 20 // ユーザーは悪くないのでサーバーエラーを返しておく 21 throw new InternalErrorException(); 22 } 23 }else{ 24 $this->Session->setFlash('入力内容に不備があります。', false); 25 } 26 } 27 28 // セレクトボックスの中身等、常にViewに渡したいものはここに書く 29 $this->set('category_items', $this->Category->find('list')); 30} 31

投稿2016/02/24 01:12

編集2016/02/24 07:05
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

smnsmn

2016/02/24 02:35 編集

Modelの()の数はコピペミスでした。失礼致しました;;; Controller側の記述が抜けておりました。 加えたところ正常にバリデーションが表示されるようになりました! 何故この記述が無いのにほかのバリデーションが動いていたのでしょうか・・・ バリデーションの際にController側の呼び出しは必須なのでしょうか? 下記のようにControllerに記述しました。 if($this->request->is('post')){  $this->Hoge->set($this->request->data);  if(!$this->Hoge->validates()){   $this->Session->setFlash('入力内容に不備があります。', false);   return;  } //ポストされた情報を整理して保存する処理 } setFlashはView側でflashしていないので、実際画面には表示されません。 バリデーションエラーの場合どう処理したら良いのかわからなくてこのように書きましたが、 実際はバリデーション後に行われる保存処理などをd_s_1さんの記述したコードの//正常の部分に記載するのでしょうか? //バリデートエラーにはバリデーションを表示させたいのでreturn;等々で良いのでしょうか? (返信コメントだと文字装飾が使えなくて見づらくて申し訳ありません。)
退会済みユーザー

退会済みユーザー

2016/02/24 07:07 編集

>何故この記述が無いのにほかのバリデーションが動いていたのでしょうか・・・ Model::save()は内部でModel::validates()を実行しますので、他のバリデーションが動作したのではないかと推測します。 「//ポストされた情報を整理して保存する処理」にて、Model::save()の第二引数に「array('validate' => false)」や「false」を指定せずに実行していませんか? (かつModel::save()に渡した保存したいデータの配列にagreeが含まれていない) >実際はバリデーション後に行われる保存処理などを//正常の部分に記載するのでしょうか? 上記の通りModel::save()はバリデートを行い、エラーが無ければ保存を行いますので、戻り値を判定してあげるだけで、Model::validates()を使用することはあまりないかと思います。 ざっくり書くとこんな感じです↓。 function register(){  if($this->request->is('post')){   if($this->Hoge->save($this->request->data)){    // 正常に保存出来たのでindexへ    $this->redirect(array('action' => 'index'));   }else{    // バリデートに引っかかったので保存出来なかった    // 特に何もせずもう一度registerを表示   }  } } バリデートに引っかかった場合にそのまま元のViewを表示させれば、FormHelper::input()にバリデートエラーの内容が表示されます。 なのでFormHelper::error()などもあまり使用することはありません。 FormHelper::error()はバリデートエラーの内容を、FormHelper::input()とは別の箇所に表示させたい場合などに使用します。 その際にはFormHelper::input()に「'error' => false」を指定し、FormHelper::input()にはバリデートエラーを表示させないようにします。 これはまさに質問のコードのViewの通りで、用法的に言えば合っています。
smnsmn

2016/02/24 05:33 編集

>Model::save()は内部でModel::validates()を実行しますので、他のバリデーションが動作したのではないかと推測します。 「//ポストされた情報を整理して保存する処理」にて、Model::save()の第二引数に「array('validate' => false)」や「false」を指定せずに実行していませんか? なるほどです。save()に対してfalseは指定していなかったので、save()対象の項目に限りバリデーションが効いていたのですね。 今回の場合だと、save()したい項目以外のagreeもバリデーションをかけたいので、2重にならないようsave()のvalidatesはfalseにしておき if($this->request->is('post')){  $this->Hoge->set($this->request->data);   if($this->Hoge->validates()){    //OKの時に行いたい処理と保存   }else{    return;   } } こんな感じでしょうか。 save()だけの場合はあまり考えずにバリデーションができるのですね。 Cakeの使い方をまだ把握しきれておりませんでした。 >バリデートに引っかかった場合にそのまま元のViewを表示させれば、FormHelper::input()にバリデートエラーの内容が表示されます。 なのでFormHelper::error()などもあまり使用することはありません。 >FormHelper::error()はバリデートエラーの内容を、FormHelper::input()とは別の箇所に表示させたい場合などに使用します。 その際にはFormHelper::input()に「'error' => false」を指定し、FormHelper::input()にはバリデートエラーを表示させないようにします。 この辺りもよく理解せずに使用しておりましたが、よく分かりました。 とても勉強になりました。 ご回答ありがとうございましたm(__)m
退会済みユーザー

退会済みユーザー

2016/02/24 05:35

解決したようで良かったです。 >こんな感じでしょうか。 そんな感じです。returnするかどうかはロジック次第ですが。 二度目のバリデートも行うべき場合はあります。仕様に合わせて臨機応変にいきましょう! 最後にそのロジックの流れで一つ書いてみました。 追記しておきますので、参考までにどうぞ。 (保存や使用するデータは適当に考えました。ご了承下さい。)
退会済みユーザー

退会済みユーザー

2016/02/24 06:50

>ogaaaanさん 重々承知の上ですが気になりますか?
smnsmn

2016/02/24 06:54

d_s_1さん 追記ありがとうございますm(__)m とても参考になりました! 特に下記部分の考え方はなるほどというか、自分では出てこなかったです。 >}else{ // ユーザー入力ままのバリデートには成功しているのに保存出来なかった // 恐らくバリデート後の情報整理のロジックに不備があったんだろう // first_name,last_nameの文字数制限はOKだけど、nameの文字数は超過したとか // ユーザーは悪くないのでサーバーエラーを返しておく throw new InternalErrorException(); } 自分の作りたい仕様をしっかり考えて実装していきたいと思います。 ------- agaaanさん ありがとうございます。参考に致します。
ogaaaan

2016/02/24 06:59

>d_s_1さん 気になるので指摘しました。
退会済みユーザー

退会済みユーザー

2016/02/24 07:07

>ogaaaan 訂正しておきました。
ogaaaan

2016/02/24 07:12

>d_s_1さん やったー! ありがとうございます! では、お騒がせしました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問