CakePHPのFlashエラーは出るが入力項目ごとのメッセージが出ないエラーの原因
CakePHP4で画面上部のフラッシュメッセージと入力ボックスに表示されるエラーメッセージ
Bakeで自動生成された Edit処理のソースを元に、少しだけ処理を追加したところ、入力エラーが発生しているのに、バリデーションのメッセージ(入力エラー)が表示されない、と言う不具合がありました。
上記の画像の「Flashメッセージ」は表示されるのですが、「バリデーションのメッセージ」が表示されないのです。
今回のこの不具合は、バリデーションエラー(入力チェックのエラー)は発生しているものの、正常な処理によるエラー処理のため(エラーログ等は出力されないため)、不具合の原因の特定に時間がかかったのですが、同じような不具合で悩んでいる方もあるのではないか、と思い記事を書きました。
原因は「エラーが発生しているときにリダイレクトしているため」でした。
この記事の内容は、CakePHP3、CakePHP4でも同じように処理できます。
ちなみに、フラッシュエラーに関しては下記にも記事を書いていますので、参考にしてください。
CakePHP4のフラッシュメッセージの表示場所、デザインを変更する方法を解説
CakePHP3 フラッシュ(FlashComponent)
https://book.cakephp.org/3/ja/controllers/components/flash.html
CakePHP4 フラッシュ(FlashComponent)
https://book.cakephp.org/4/ja/controllers/components/flash.html
エラーが発生したときの処理でリダイレクトをしていませんか?
CakePHP4の入力フォームで、バリデーションエラー(入力エラー)がある場合、画面上部に表示される Flashのエラーメッセージは表示されるものの、入力エラーがある項目の下にエラーメッセージは表示されない、という不具合の一つの原因をご紹介します。
今回の記事は、上記の不具合の原因の一例のご紹介です。
プログラムの文法には不具合はないため、原因が分かりにくいものです。
不具合の原因は多種多様です。
ですが、この記事で紹介したような不具合もあるよ!これで解決する方が一人でもいれば!という感じで書いています。
Bakeで自動生成されるデフォルトのソースコードを元に解説
下記は Bakeで自動生成されたソースコードの一部です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public function edit($id = null) { $topic = $this->Topics->get($id, [ 'contain' => [], ]); if ($this->request->is(['patch', 'post', 'put'])) { $topic = $this->Topics->patchEntity($topic, $this->request->getData()); if ($this->Topics->save($topic)) { $this->Flash->success(__('The topic has been saved.')); return $this->redirect(['action' => 'index']); } $this->Flash->error(__('The topic could not be saved. Please, try again.')); } $this->set(compact('topic')); } |
入力エラーが発生すると
$this->Flash->error(__('The topic could not be saved. Please, try again.'));
の処理が実行されます。
ここで処理されたメッセージは、レイアウト「/templates/layout/default.php」に記述されている
= $this->Flash->render() ?>
で処理されて表示されます。
あわせて、入力項目の
echo $this->Form->control('topics_date');
で処理されて、バリデーションエラー(入力エラー)のメッセージが入力項目の下に表示されます。
デフォルトのソースコードを元に改変したソースコード
今回の不具合は、デフォルトの処理を少し改変し、ログを保存する処理を追加して下記のような処理にしていました。
この場合、バリデーションエラー(入力エラー)があった場合、Flashのメッセージは表示されるのですが、入力項目ごとのエラーメッセージは表示されません。
どこが間違っているか分かりますか?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
try { $topic = $this->Topics->patchEntity($topic, $this->request->getData()); if ($this->Topics->save($topic)) { // ログを保存する $response = $this->Common->saveLog($topic); if(!$response){ throw new \Exception(__('The topic log could not be saved. Please, try again.')); } } else { throw new \Exception(__('The topic could not be saved. Please, try again.')); } $this->Flash->success(__('The topic has been saved.')); return $this->redirect(['action' => 'index']); } } catch (\Exception $e) { $this->Flash->error(__($e->getMessage())); return $this->redirect(['action' => 'edit', $id]); } |
不具合の原因は、17行目の「return $this->redirect(['action' => 'edit', $id]);
」の部分になります。
上記の処理では、バリデーションエラーが発生した場合は 17行目でリダイレクトをしていますので、表示されている画面は、入力をする前の状態の画面が再度表示されているだけですので、入力項目ごとのエラーメッセージは表示されません。
ですが、16行目の「$this->Flash->error(__($e->getMessage()));
」で処理している Flashメッセージに関しては、リダイレクトをしてもメッセージを受け取って表示をしてくれるのです。
これはこれで便利な機能なんですが、今回のような不具合の原因につながるのです。
処理の内容を確認すれば当たり前と言えば当たり前なんですが、Flashのエラーメッセージは表示されているため、リダイレクトされていることに気づきにくいんですよね。
処理は正しく行われており、バリデーションのエラーメッセージが表示されていない、
という不具合だと誤認してしまうのです。
そうするとなかなか不具合の原因に行き当たらないわけです。
プログラムの不具合はないけれど、入力項目ごとのエラーメッセージが表示されない。
そんな不具合が発生したときに原因に気づくきっかけになれば、と思っています。
CakePHP4の関連記事
CakePHP4系でJSONレスポンスの処理ではwithStringBodyを使う。3との違い解説CakePHP4、CakePHP5の「warning: DebugKit is disabling...」の対処方法
MySQL+CakePHPのdate型、datetime型項目は「2999-12-31」までしか扱えない
CakePHP4のFrozenDateで1ヵ月前、先月、今月1日、来月末の日付などを算出する方法
CakePHP4のcake cache clear_allでPermission deniedはパーミッションの変更が必要
CakePHP4のクリエビルダーを使用してOR条件をAND条件でつなぐSQL文を作る方法
CakePHP4のController内でViewテンプレート、レイアウトの変更設定を記述する方法
CakePHP4から外部のデータベースにアクセスする方法解説
CakePHP4の数値項目は「like %10%」の部分一致検索(find select)はできない
CakePHP4でロギングスコープやログレベルを使用してログを出し分ける方法を解説
その他の「CakePHP4」に関する記事一覧
GoogleAdwords
GoogleAdwords
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
-
CakePHPで favicon.icoやapple-touch-icon-144-precomposed.pngが could not be foundのエラーが出るときの対処方法
CakePHPで「CakeDC/Users」などルーティングを行うプラグインを利用するときに、favicon.icoやapple-touch-icon-144-precomposed.pngがNotFoundエラーになることがある。その対処方法の解説。
-
-
CakePHP4のCakeDC/Usersの画面、メール本文テンプレートのカスタマイズ方法解説
CakeDC謹製Usersプラグインの紹介。ユーザ新規登録の流れを紹介しつつ、テンプレートファイル、設定情報ファイルの場所とそれらをカスタマイズする方法を説明します。
-
-
CakePHP3で環境変数を設定して本番環境と開発環境を分けて処理をする場合
CakePHP3で開発環境と本番環境とで違う設定ファイルを読み込ませて環境ごとに定数を切り替える方法を解説。Apacheのhttpd.confに環境変数を設定し、それを読み込み判別する。
-
-
CakePHP4でcontrollerで実行したバリデーションエラーをmodelのにマージする方法
CakePHP4でcontrollerで実行したバリデーションの結果をModelのバリデーション結果に追加するメソッド「setError()」「setErrors()」の使い方の解説。
-
-
CakePHP3チュートリアルで日付と時刻のDateTimeでエラーが出たときの対処方法
CakePHP3のブックマークチュートリアルには記載ミスもあり、そのまま動かない個所もある。CakePHP3では namespaceを使うようになったので、classを呼び出すときに¥を追加する必要が!
-
-
CakePHP 2.3 テーブルの項目を演算した結果を条件として抽出する方法
アソシエーション(連携)している先のテーブルの項目で演算をする場合の考え方と注意点をサンプルソースを用いて説明しています。分かってしまえば簡単です。
-
-
CakePHP3のインストールでURL rewriting……のエラーが!その解決方法解説
CakePHP3をインストールしたら URL rewriting is not properly configured.のエラーが。原因は.htaccessが有効になっていないこと。httpd.confに設定を追加すればOK。
-
-
CakePHP4のユーザ管理・ログイン認証プラグインCakeDC/Usersのインストール解説
CakePHP4のユーザ管理プラグイン Usersは、ユーザ登録、メール認証、ログイン認証、ユーザ管理、権限管理、reCAPTCHAなど会員制のサイトを簡単に実現可能。その導入方法、カスタマイズ方法を解説。
-
-
CakePHP 2.3 ID以外のカラムでアソシエーション(連携)をさせる場合
ID以外のカラムでアソシエーション(連携)させるための考え方とサンプルソースを用いての説明を行っています。
-
-
CakePHP3のcontroller内でテンプレート、レイアウトを変更する際の指定方法
CakePHP3でテンプレートファイルやレイアウトファイルをデフォルトのものから別のものに変更したい場合の指定方法を解説。