cakePHPはデータをDBに保存する場合に使用するメソッドの一つ「save()」というものを使用しますが、これを使ってDBに保存できなかった場合は、Debugで確認してもfalseでしか返ってきません。

そもそもフォームから飛んできた値がバリデーションで弾かれたのか、必要なデータが飛んできてもないのか。

ちなみに保存前にpatchEntityで確認してもfasErrorsはfalseだったので、入力で飛んできた値には問題なさそうでした。

何がダメだったのかを知りたいのに、プログラム文を見直したり書き直して思い当たる場所を色々と触っても結果が変わらないのにはとてもイライラします。

時間だけが過ぎ、ストレスもたまり、cakePHPでの開発すら辞めたくなります。

ネットでよく見かける解決方法は、try catchの例外処理で確認することのようです。

見かけるプログラムは以下のような感じ。

try {
$table->saveOrFail($entity);
} catch (\Cake\ORM\Exception\PersistenceFailedException $e) {
$e->getEntity();
}

これはCakePHPの公式ページにも載っているものでした。

どのような感じになるかというと、save()ではなくsaveOrFail()を使用してもう少し厳密な保存をすることだそう。

やってみると確かにcatchの部分を通ってechoでなにか表示されましたが、saveOrFail()の時に渡した$sentityの中身を変換し直した内容が表示されただけでした。

そこで、今度は以下のように変えてみました。

try {
$table->saveOrFail($entity);
} catch (\Cake\ORM\Exception\PersistenceFailedException $e) {
debug($e);
}

すると、前回とは違う中身で、さらに他のメッセージも加わった状態で表示されました。多くの情報がオブジェクトで取得でき、その中から確認しやすいキーがありました。

キー「message」の中身に「 ‘Entity save failure. Found the following errors (user_id._existsIn: “This value does not exist”).’」というのがありました。

調べてみると、Userテーブルのidに指定した値に該当するデータはありませんよというものだそう。

つまりリレーションでUserテーブルにある情報を取り出そうとして、見つかりませんというエラーがあったため、保存が出来なかったということになるようです。

その後、user_idに代入する値を見直し、再度save()実行するとエラーなく保存できました。

やはり、エラーの内容が分かるととても助かります。そういうメッセージを吐き出す機能が用意されているCakePHPはよくできたフレームワークだと思います。

ちなみに、吐き出したエラーのキー「_entity」の中に「errors」というのがあり、そこには指定するカラムとエラーの種別が指定されていました。

もしsave()で保存できない場合、色々と見直す作業で多くの時間を使うよりも、まずはsaveOrFail()で例外処理でメッセージ確認したほうが効率が良くなると思います。