Laravel Accessors and Mutators (Modern Attribute Syntax)

Laravel accessors and mutators with the modern Attribute::make() syntax – get/set examples, old getXAttribute comparison, casting, and when to use each.

Accessors and Mutators

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.

Comments

comments