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のFrozenDateで1ヵ月前、先月、今月1日、来月末の日付などを算出する方法CakePHP4のcake cache clear_allでPermission deniedはパーミッションの変更が必要
CakePHP4のクリエビルダーを使用してOR条件をAND条件でつなぐSQL文を作る方法
CakePHP4のController内でViewテンプレート、レイアウトの変更設定を記述する方法
CakePHP4から外部のデータベースにアクセスする方法解説
CakePHP4の数値項目は「like %10%」の部分一致検索(find select)はできない
CakePHP4でロギングスコープやログレベルを使用してログを出し分ける方法を解説
CakePHP2、CakePHP3、CakePHP4、CakePHP5のバージョンを調べる 2つの方法
Windows上のXAMPP環境のCakePHPのコマンド実行時に環境変数を指定する方法
CakePHP4で複数の引数(パラメータ)を付与してコマンドを実行する方法
その他の「CakePHP4」に関する記事一覧
GoogleAdwords
GoogleAdwords
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
-
CakePHP3のForm Helperの使い方のまとめ
CakePHP3になりフォームヘルパーの使い方も大きく変わりましたので、使い方をまとめました。基本的な使い方からプラスアルファの便利な使い方まで紹介。
-
-
CakePHP 2.3でファイルのアップロード処理を作る
CakePHPでプラグインを使わないファイルアップロード処理を解説します。簡単です。DBにファイルを格納する方法も。
-
-
CakePHP 2.3 コマンドラインからPHPのシェル実行の方法解説
CakePHP 2.3でコマンドラインから CakePHPで記述した処理を実行する方法を解説します。
-
-
VirtualBoxにCakePHP3を設置。必要なCentOS、Apache、PHP、MySQL、Composerをインストールし設定する
VirtualBoxにCentOS、Apache、MySQL、PHPをインストールするところから初めてCakePHP3の開発環境を構築する手順を詳細解説。この記事1つで全ての設定が完了する。
-
-
CakePHP3でQRコードを作成、表示するライブラリ「cakePHP-QR-Code-Helper」
CakePHPでQRコードを生成するライブラリ「cakePHP-QR-Code-Helper」の紹介。GDライブラリのインストールも必要ないHelperとして提供されているため、ファイルを設置すればすぐに使用可能。
-
-
CakePHP3でWarning Error: SplFileInfo::openFile()エラーが発生した場合の対処方法
CakePHP3のキャッシュファイルのパーミッションエラー Error: SplFileInfo::openFile()が発生した場合の対応方法解説。app.phpにキャッシュファイルのパーミッション設定を行い、既存のファイルは削除。
-
-
CakePHP3のデバッグキット(DebugKit)を強制的に有効、無効に変更する方法
CakePHP3に付属しているデバッグのためのツール、デバッグキットを強制的に有効化、無効化する方法を解説。初期設定では開発環境としてありそうなドメインの場合のみ有効になるように設定されている。
-
-
CakePHP4で公開側と管理側のデザインテンプレートを分ける方法・setLayout()
CakePHP4でデフォルトのレイアウトファイル「default.php」は管理側に使用し、これとは別のデザインを公開側のページに設定したい、を実装する方法を解説。
-
-
CakePHP4の規約外のカラムをキーにアソシエーション(テーブル連結)する方法
CakePHPで規定外のカラム名のキーを指定してアソシエーション(テーブル連結)をする方法を解説。アソシエーション名によってはミスが発生しやすい点もあるので注意も必要。
-
-
CakePHP3で /Layout/defult.ctpにある titleタグ、h1タグを編集する方法
CakePHP3でtitleタグ、h1タグのテキストをデフォルトから変更する方法を解説。テンプレートファイルに「$this->assign()」でテキストを指定して「/Layout/defult.ctp」で受け取る。