DEV3 Technologies home

DEV3 Developer Forum

How do I write accessors and mutators in modern Eloquent (Attribute class)?

Laravel helpSolved0 views
dev3 ·

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?

#laravel#eloquent

0

1 reply

dev3 · Accepted answer

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 $hidden to protect sensitive data you also expose via $appends.
0

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.