Add a custom attribute to a Laravel / Eloquent model on load? Add a custom attribute to a Laravel / Eloquent model on load? laravel laravel

Add a custom attribute to a Laravel / Eloquent model on load?


The problem is caused by the fact that the Model's toArray() method ignores any accessors which do not directly relate to a column in the underlying table.

As Taylor Otwell mentioned here, "This is intentional and for performance reasons." However there is an easy way to achieve this:

class EventSession extends Eloquent {    protected $table = 'sessions';    protected $appends = array('availability');    public function getAvailabilityAttribute()    {        return $this->calculateAvailability();      }}

Any attributes listed in the $appends property will automatically be included in the array or JSON form of the model, provided that you've added the appropriate accessor.

Old answer (for Laravel versions < 4.08):

The best solution that I've found is to override the toArray() method and either explicity 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);        }}

or, if you have lots of custom accessors, loop through them all and apply them:

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


The last thing on the Laravel Eloquent doc page is:

protected $appends = array('is_admin');

That can be used automatically to add new accessors to the model without any additional work like modifying methods like ::toArray().

Just create getFooBarAttribute(...) accessor and add the foo_bar to $appends array.


If you rename your getAvailability() method to getAvailableAttribute() your method becomes an accessor and you'll be able to read it using ->available straight on your model.

Docs: https://laravel.com/docs/5.4/eloquent-mutators#accessors-and-mutators

EDIT: Since your attribute is "virtual", it is not included by default in the JSON representation of your object.

But I found this: Custom model accessors not processed when ->toJson() called?

In order to force your attribute to be returned in the array, add it as a key to the $attributes array.

class User extends Eloquent {    protected $attributes = array(        'ZipCode' => '',    );    public function getZipCodeAttribute()    {        return ....    }}

I didn't test it, but should be pretty trivial for you to try in your current setup.