Add a Custom Attribute to a Laravel/Eloquent Model on Load

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

}

I want to add a custom attribute to model in laravel

In your model, add this:

protected $appends = ['readable_created_at'];

public function getReadableCreatedAtAttribute()
{
return $this->created_at; //or however you want to manipulate it
}

After which, you can access it like normal, e.g. $user->readable_created_at.

Read more at the Laravel Doc here.

Add custom attribute in eloquent model

Use a combination of Mutators and the $appends property. Here's an example:

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Place extends Model {

protected $appends = ['center'];

public function getCenterAttribute()
{
return $this->point($this->getRawAttribute("area"));
}

protected function point($area)
{
// logic for SQL POINT(), etc
}
}

The $appends property will mean that the mutated attribute is included in JSON/array output when $model->toJson() or $model->toArray() is called (which Response::json() does)

The reason for doing point logic in code is because with eloquent models, you'd hit the N+1 query problem when fetching a list of places and their centers, and that's not a great idea for your database.

Your query wouldn't be used when fetching data for the model from the database, either, since the default query for models is

select * from `table` where id = :id

Which is then figured out internally to set up data on the model.



Related Topics



Leave a reply



Submit