Laravel 9.35 Model::preventAccessingMissingAttributes を試しつつ、注意点にも触れてみる
前書き
Laravel 9.35 の新機能の1つ、Model::preventAccessingMissingAttributes() を試してみましたので、その様子とついでに注意点についても触れてみたいと思います。
[9.x] Opt-in Model::preventAccessingMissingAttributes() option #44283
本題
少し長いメソッド名ですが、この機能、要はバグを減らすための機能です。
今までの Laravel では、Eloquent モデルで存在しないプロパティにアクセスしても、特にエラーは出ずに、null が返されてスルーされていましたが、それを防ぐ(エラーとする)事ができる機能です。
この機能をオンにするには、例えば、AppServiceProvider で以下のように記述します。
<?php
use Illuminate\Database\Eloquent\Model;
class AppServiceProvider extends ServiceProvider
{
// 略
public function boot()
{
// 本番環境以外で有効にする
Model::preventAccessingMissingAttributes(! $this->app->isProduction());
}
}
これでオンになりました。
で、エラー(例外)が出るのは、「(1) 存在しないプロパティにアクセスしようとして(accessors / casts / relations 等は除く)」且つ「(2) そのモデルがDBに存在する時」のみです。言い換えれば、DBに保存していないモデルは、この機能の対象ではありません。例えば下記みたいなケースです。(DBにはデータがある前提)
(2024年1月追記:Ver.10.40 辺りからは、casts にも改良が加わっています)
// ケース1
$user = User::first();
$user->emailll; // email の綴りミス
// ケース2
$user = User::select('id', 'name')->first();
$user->email; // select() に email を追加忘れ
今までですと、単に null となってスルーされていましたが、この機能をオンにしていると、、、
Illuminate \ Database \ Eloquent \ MissingAttributeException
The attribute [emailll] either does not exist or was not retrieved for model [App\Models\User].
みたいなエラーとなって、処理が終了します。これで不要なバグの心配をしなくて済みます。
Model::shouldBeStrict()
そして、このプルリクがマージされる直前に Taylor さんによって、shouldBeStrict() というメソッドが追加されました。
これは何かと言うと、既に以前から存在する機能の preventLazyLoading() と preventSilentlyDiscardingAttributes() と今回の機能をまとめて有効に出来るメソッドです。
ですので、AppServiceProvider で、
use Illuminate\Database\Eloquent\Model;
public function boot()
{
Model::shouldBeStrict(! $this->app->isProduction());
}
とやっておけば、開発環境でまとめて3つ設定した事になります。楽でいいですね。
注意点⚡⚡⚡
例によって、注意点があります。今回の機能を有効にする際は、
// 正解
Model::preventAccessingMissingAttributes();
// 不正解(prevents と最後に s がある。こちらは設定状況を返す)
Model::preventsAccessingMissingAttributes();
どちらもメソッドは存在しますので、この罠に掛からないようご注意下さい。掛かってしまうと、設定したつもりが、実は設定されていないという事になってしまいます。
(以前、同じような事を書いた記憶がありますが…)
で、最初にこの罠に掛かってしまった方は、、、、、そう、あの Taylor さんですね。😅
先程の shouldBeStrict() メソッド内のこの機能を有効にする箇所で、上記をミスっていて、そのままマージされていました。
で、犬も歩けば棒に当たる理論で、たまたまプルリクなどを見ていた私が気づいたので、それの修正用のプルリクを送り、マージされました。
[9.x] Fix method name in shouldBeStrict method #44520
修正箇所、たった1文字。修正箇所の少なさでは、かなりの上位です。まぁ、自分で言うのも何ですが、私のスキルレベルに見事マッチしたプルリクですね。(^3^)ぷっ
Taylor さんも間違えてしまうという事は、まぁ、皆間違えてしまいますよ…。
という事で、バグを減らす機能のオンでバグらないようご注意下さい。
と、、、これで終わっていれば良かったのですが、先程公開されたと思われる Laravel News でもミスってる…🤣
いや~、どうした事か。Laravel News にプルリク送る?そんなの無いでしょ…💦
雑感
今日はこの辺で失礼します😪
Discussion