N+hundreds, using this Attribute Accessor approach?
When I use this earlier convention of a model attribute accessor:
use App\Services\LocationService;
use App\Models\Location;
//
public function getDistanceToOfficeAttribute()
{
$office = Location::office()->first();
return LocationService::distance(
origin: $this->navigationAddress,
destination: $office->navigationAddress
);
}
and then something like this in blade:
@php
$cachedDistance = $user->distanceToOffice;
@endphp
<div>
Distance to office: {{ $cachedDistance->distance }}les
(about {{ $cachedDistance->duration['in_traffic'] }})
</div>
... the database query generated by Location::office()->first() fires twice, and I can observe this duplicate in the Laravel debugbar.
I'd like to prevent this duplicated database query, of course..
But here's where it gets wild and I don't understand why; when I opt in to a typed Attribute Accessor, like this one:
use Illuminate\Database\Eloquent\Casts\Attribute;
use App\Services\LocationService;
use App\Models\Location;
//
public function distanceToOffice(): Attribute
{
$office = Location::office()->first();
$distanceFn = fn() => LocationService::distance(
origin: $this->navigationAddress,
destination: $office->navigationAddress
);
return Attribute::make(get: $distanceFn)
->shouldCache()
;
}
still using the same blade template, suddenly the db query generated by Location::office()->first() is invoked hundreds of times; around 325 times, in fact. And I don't understand why or how.
EDIT
And a few minutes later, I modified the latter accessor as follows:
public function distanceToOffice(): Attribute
{
# resolve the model later
$resolveOffice = fn() => Location::office()->first();
$distanceFn = fn() => LocationService::distance(
origin: $this->navigationAddress,
destination: $resolveOffice()->navigationAddress
);
return Attribute::make(get: $distanceFn)
->shouldCache()
;
}
Such that the office location model is resolved/loaded when that Attribute's getter function is actually called (I guess?).. and now the duplicate query is back down from 320-something, to just 2x.
I still would like to understand the how the upwards of 300 invocations is occurring; one User (or Teacher) model and one Location model involved here.
Please or to participate in this conversation.