Home  >  Article  >  Backend Development  >  How to Add Custom Attributes to Laravel Eloquent Models on Load?

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

Patricia Arquette
Patricia ArquetteOriginal
2024-11-01 07:41:30754browse

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:

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

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:

<code class="php">class EventSession extends Eloquent {

    protected $table = 'sessions';

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

Laravel Versions < 8:

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:

<code class="php">class EventSession extends Eloquent {

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

    public function getAvailabilityAttribute()
    {
        return $this->calculateAvailability();  
    }
}<p><strong>Option 2: Override toArray() Method</strong></p>
<p>Alternatively, you can override the toArray() method and manually set the attribute:</p>
<pre class="brush:php;toolbar:false"><code class="php">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);    
    }

}</code>

Option 3: Loop Through Mutated Attributes

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

<code class="php">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);    
    }

}</code>

The above is the detailed content of How to Add Custom Attributes to Laravel Eloquent Models on Load?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn