Menü schliessen
Created: July 2nd 2025
Categories: IT Development,  Laravel
Author: Nikola Jevtic

Modern Eloquent Accessors and Mutators with Laravel’s Attribute Objects

Introduction

Laravel has long supported model accessors and mutators via getXAttribute and setXAttribute methods. While powerful, they can get messy — especially in large models with many fields.

Starting in Laravel 9, you can now define cleaner and more expressive accessors/mutators using Attribute objects. This modern approach makes your models easier to read, test, and maintain — especially when paired with enum or value object casting.

In this post, we’ll walk through how Attribute objects work, show common real-world examples, and compare them to the legacy method.


What Is an Attribute Object in Laravel?

Laravel's Illuminate\Database\Eloquent\Casts\Attribute class lets you define both an accessor and a mutator in a single method:

use Illuminate\Database\Eloquent\Casts\Attribute;

public function name(): Attribute
{
    return Attribute::make(
        get: fn($value) => ucfirst($value),
        set: fn($value) => strtolower($value),
    );
}

This is equivalent to getNameAttribute() and setNameAttribute().

✅ Benefits

  • Less boilerplate
  • Method name is clean (name() instead of getNameAttribute())
  • Clearly groups getter/setter logic
  • Testable and expressive

Basic Example: Formatting a Name Field

Legacy Style

public function getNameAttribute($value)
{
    return ucfirst($value);
}

public function setNameAttribute($value)
{
    $this->attributes['name'] = strtolower($value);
}

With Attribute Object

public function name(): Attribute
{
    return Attribute::make(
        get: fn($value) => ucfirst($value),
        set: fn($value) => strtolower($value),
    );
}

Cleaner and encapsulated.


Advanced Example: Use with Enum or Value Object

You can combine Attribute objects with enum casting or DTO-style logic.

use App\Enums\UserStatus;

public function status(): Attribute
{
    return Attribute::make(
        get: fn($value) => UserStatus::from($value),
        set: fn(UserStatus $status) => $status->value,
    );
}

Now you can safely work with enum instances throughout your app:

$user->status = UserStatus::Active;
echo $user->status->value;

Mutating Input Before Save

public function email(): Attribute
{
    return Attribute::make(
        set: fn($value) => strtolower(trim($value)),
    );
}

This ensures consistent storage format with minimal effort.


Computed Attributes (Access Only)

Sometimes you only need a virtual field for output:

public function fullName(): Attribute
{
    return Attribute::make(
        get: fn() => $this->first_name . ' ' . $this->last_name,
    );
}

This full_name doesn’t exist in the DB — but you can use it like a real attribute:

echo $user->full_name;

Best Practices

  • Use Attribute::make() to define simple, inline accessors/mutators
  • Pair with type hints (e.g. UserStatus, int, bool) for safer domain logic
  • Document virtual (computed) attributes in resource classes or API docs
  • Avoid overcomplicating — logic-heavy casts may belong in custom Cast classes instead

Conclusion

Laravel’s Attribute object is the modern way to define clean, type-safe model accessors and mutators. Whether you're formatting a name, storing enums, or building computed values, this feature helps you write less code with more clarity.

Ditch those bulky getXAttribute/setXAttribute methods — and make your models more elegant today!