【CakePHP3】特定レコードのsave()だけ失敗する時はsaveOrFail()を使ってみよう

Bake-with-CakePHP Logo

CakePHP3で作ったバッチがどういうわけかよくsave()で失敗してて、しかもExceptionすら吐かずにfalseだけ返すものだから

「一体原因は何なんだろ?」

って思うことがしょっちゅうあったので、その解決策を書いておく。検証したCakePHPのバージョンは3.6.13。

save()がよく失敗する時はsaveOrFail()を使うようにしよう

save()で失敗してfalseが返ってくる場合、実際にはExceptionを吐く条件が満たされていることが多い。個人的な体験談としては、save()しようとしたEntityに該当するTableにbuildRules()が設定されていて、外部キールールに引っかかって実際にはExceptionを吐く条件を満たしていたことがあった。

 

例えば、保存しようとするEntityに該当するTableに、buildRules()として

等が書いてあったら要注意。PersistenceFailedExceptionがthrowされる可能性がありうる。

 

このように、Exceptionを吐き出しうるケースで実際にExceptionをthrowさせて検知する為にはsave()の代わりにsaveOrFail()を使おう。内部処理でやっていることはsave()と同じだが、Exceptionがあったらちゃんとthrowしてくれる堅実性があるので便利。

基本的な保存処理はsave()よりもsaveOrFail()のほうが良いのか?

ここまでの話の流れから察するに、

「基本的な保存処理はsave()よりもsaveOrFail()を使ったほうが良いのでは…」

と思わなくもない。

 

これに関しては、buildRules()で厳密に外部キーを見ているようなレコードを保存する時にだけsaveOrFail()を使うと良いと思った。そのように使い分けていれば、コードの読み手としては

「あー、このレコードは外部キーなどを厳密に考慮して保存する必要があるのね」

って解釈できるから。