Older tutorials use getFirstNameAttribute and setPasswordAttribute. In Laravel 12 I saw an Attribute::make syntax and casts() method. How do I define accessors, mutators and casts the current way?
DEV3 Developer Forum
How do I write accessors and mutators in modern Eloquent (Attribute class)?
Every post is reviewed first. Usually reviewed within 24 hours.
1 reply
Since Laravel 9 the old getXAttribute naming still works, but the recommended style is a protected method returning Illuminate\Database\Eloquent\Casts\Attribute. The method name is the camelCase attribute name.
use Illuminate\Database\Eloquent\Casts\Attribute;
class User extends Model
{
protected function fullName(): Attribute
{
return Attribute::make(
get: fn () => "{$this->first_name} {$this->last_name}",
);
}
protected function email(): Attribute
{
return Attribute::make(
get: fn (string $value) => strtolower($value),
set: fn (string $value) => strtolower(trim($value)),
);
}
}
Use it as a normal property: $user->full_name. Computed attributes that do not exist in the DB appear in arrays and JSON only if you add them to $appends.
Casts
In Laravel 11 and 12 you can define casts in a method, which allows enum classes and arguments:
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
'settings' => 'array',
'status' => OrderStatus::class, // backed enum
'is_active' => 'boolean',
'price' => 'decimal:2',
];
}
The $casts property is still supported. The hashed cast hashes passwords automatically on assignment, so you no longer call Hash::make in the controller. Do not double-hash.
Performance tip: expensive computed values (API calls, queries) should be avoided in accessors. ->shouldCache() on the Attribute only caches the value on that model instance, not across requests.
Pitfalls
- Accessors run on every access and in
toArray(), so avoid queries inside them (N+1). - A mutator is not applied to mass update queries (
Model::where(...)->update()), only to model instances. - Do not use
$hiddento protect sensitive data you also expose via$appends.