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);
}
}
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