Open
Description
Laravel Version
12.2
PHP Version
8.4.1
Database Driver & Version
No response
Description
All model accessors are called when calling toArray
on a model, even if they aren't included in the array.
Consider the following:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Foo extends Model
{
protected $visible = [
'id',
'name',
];
protected function location(): Attribute
{
return Attribute::make(
get: fn () => 'Paris',
);
}
}
When calling toArray
getMutatedAttributes
is always run and then filtered down to just the arrayable attributes.
Why does this matter ?
Because with a more complex Attribute
accessor that relies on a relation, you introduce potential eager-loading issues when using API resource collections , e.g.
protected function timezone(): Attribute
{
return Attribute::make(
get: fn () => $this->location->timezone,
);
}
Steps To Reproduce
- Create a model with an accessor that dumps or logs when run, but don't include it in
visible
/appends
. - Call
toArray
on the model and observe that the accessor was run.