Could we help you? Please click the banners. We are young and desperately need the money
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.
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
public function getNameAttribute($value) { return ucfirst($value); } public function setNameAttribute($value) { $this->attributes['name'] = strtolower($value); }
public function name(): Attribute { return Attribute::make( get: fn($value) => ucfirst($value), set: fn($value) => strtolower($value), ); }
Cleaner and encapsulated.
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;
public function email(): Attribute { return Attribute::make( set: fn($value) => strtolower(trim($value)), ); }
This ensures consistent storage format with minimal effort.
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;
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!