"If a worker wants to do his job well, he must first sharpen his tools." - Confucius, "The Analects of Confucius. Lu Linggong"
Front page > Programming > How to add custom properties when Laravel Eloquent model is loading?

How to add custom properties when Laravel Eloquent model is loading?

Posted on 2025-04-15
Browse:639

How to Add Custom Attributes to Laravel Eloquent Models on Load?

How to Add Custom Attributes to Laravel Eloquent Models on Load?

In Laravel Eloquent, you may encounter a scenario where you want to add a custom attribute to a model when it's loaded. For example, consider a controller like this:

public function index()
{
    $sessions = EventSession::all();
    foreach ($sessions as $i => $session) {
        $sessions[$i]->available = $session->getAvailability();
    }
    return $sessions;
}

It would be convenient to skip the manual loop and have the 'available' attribute populated automatically.

The Problem

The issue here is that the toArray() method of a model ignores accessors that don't correspond to columns in the underlying table. This is an intentional design for performance reasons.

The Solution

Laravel Versions >= 8:

Luckily, there's an elegant way to achieve this using the Attribute class:

class EventSession extends Eloquent {

    protected $table = 'sessions';

    public function availability()
    {
        return new Attribute(
            get: fn () => $this->calculateAvailability()
        );  
    }
}

Laravel Versions

Option 1: Appends Property

For versions less than 8, you can use the $appends property to control which attributes are included in the serialized form of the model:

class EventSession extends Eloquent {

    protected $table = 'sessions';
    protected $appends = array('availability');

    public function getAvailabilityAttribute()
    {
        return $this->calculateAvailability();  
    }
}

Option 2: Override toArray() Method

Alternatively, you can override the toArray() method and manually set the attribute:

class Book extends Eloquent {

    protected $table = 'books';
    
    public function toArray()
    {
        $array = parent::toArray();
        $array['upper'] = $this->upper;
        return $array;
    }
    
    public function getUpperAttribute()
    {
        return strtoupper($this->title);    
    }

}

Option 3: Loop Through Mutated Attributes

If you have numerous custom accessors, you can iterate through them and apply them during serialization:

class Book extends Eloquent {

    protected $table = 'books';
    
    public function toArray()
    {
        $array = parent::toArray();
        foreach ($this->getMutatedAttributes() as $key)
        {
            if ( ! array_key_exists($key, $array)) {
                $array[$key] = $this->{$key};   
            }
        }
        return $array;
    }
    
    public function getUpperAttribute()
    {
        return strtoupper($this->title);    
    }

}
Latest tutorial More>

Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.

Copyright© 2022 湘ICP备2022001581号-3