Last updated: July 2026 — covers the Attribute::make() syntax used since Laravel 9
An accessor transforms a value when you read it from a model; a mutator transforms it when you write it. Since Laravel 9 both live in a single method returning an Attribute object — if you learned the old getNameAttribute() style, here’s the translation.
The modern syntax
use Illuminate\Database\Eloquent\Casts\Attribute;
class User extends Model
{
protected function name(): Attribute
{
return Attribute::make(
get: fn (string $value) => ucwords($value), // accessor
set: fn (string $value) => strtolower($value), // mutator
);
}
}
$user->name = 'MITESH PATEL'; // stored as "mitesh patel"
echo $user->name; // displayed as "Mitesh Patel"
The method name is the camelCase form of the column (first_name → firstName()).
Old vs new, side by side
// Laravel 8 and earlier — still works, but legacy
public function getNameAttribute($value) { return ucwords($value); }
public function setNameAttribute($value) { $this->attributes['name'] = strtolower($value); }
One method instead of two, and the get/set pair is impossible to misname.
Computed attributes (no column required)
protected function fullName(): Attribute
{
return Attribute::make(
get: fn () => "{$this->first_name} {$this->last_name}",
);
}
$user->full_name now works anywhere. To include it in JSON output, add protected $appends = ['full_name'];.
Accessors that use multiple columns
The get closure receives the raw value and the full attribute array:
protected function address(): Attribute
{
return Attribute::make(
get: fn ($value, array $attributes) =>
$attributes['street'] . ', ' . $attributes['city'],
);
}
Accessor, or cast?
If you’re only converting types — dates, booleans, JSON to array, encrypted strings, enums — use $casts instead; it’s declarative and covers both directions automatically:
protected $casts = [
'settings' => 'array',
'is_admin' => 'boolean',
'verified_at' => 'datetime',
];
Reach for Attribute::make() when there’s real logic: formatting, combining columns, normalizing input. And for enum casting specifically, I’ve written a dedicated guide: Laravel enum casting.
Gotcha worth knowing: accessors run on attribute access, not in SQL — User::where('full_name', ...) will not work, because the database has no such column. Query the underlying columns instead.
