Something I am often asked is can you have a virtual field in a model. Well yes you can. Laravel has a feature "Accessors" which is really useful.

Something I am often asked is can you have a virtual field in a model. Well yes you can. Laravel has a feature "Accessors" which is really useful.

For example in your users table you have a first name and a last name and you are fed up with writing something like:

$name = $user->first_name." ".$user->last_name;
{{$name}}

Just define an access in your model which can contain any logic you like. So we could use:

function getFullNameAttribute() {
return sprintf('%s %s', $this->first_name, $this->last_name);
}

The sprintf here turns the objects into a string.

You can put whatever logic you like in the function. For example here is one I have:

function getCarouselTypeNameAttribute() {
    switch($this->carouselType)    {   
              case 1: return "SIMPLE";break;
              case 2: return "COMPLEX";break;
              }
}

You now have access to this vritual field:

User::latest()->first->full_name

BUT.........................

This is a virual field that will not show up if you return a collection.

Is there a way around this I hear you cry!!!

Yes and it is simple. Add the protected $appends attribute to your model. It accepts an array with one or multiple fields that should automatically be appended from now. This is how it looks like with our last_name field:

protected $appends = ['full_name'];

It will now show up in the collection.

If you dd it will show in an appends line.

Mutators are the opposite of Accessors. You can use them for really cool stuff.

For example, to convert different inputs.

Let’s show you something. Imagine you want to save a kind of time period. Usually, you always save the smallest possible unit. In our case seconds. For UX reasons, the user doesn’t want to enter seconds, but for example, minutes in one place, or hours in another place. It can all be solved very quickly.

public function setDurationInMinutesAttribute($value){
   $this->attributes['duration_in_seconds'] = $value * 60;
}
public function setDurationInHoursAttribute($value){
   $this->attributes['duration_in_seconds'] = $value * 60 * 60;
}

So we have two virtual fields which we can use in a store function:

$video->update([
'title' => request('title'),
'duration_in_minutes' => request('duration_in_minutes'),
]);

This saves you the calculation in the controller, and you can simply use a non-existent column and use a mutator to map it correctly to the correct column while performing some calculations.

Hope you find this tip useful - I use it all the time!!

YOUR REACTION?



Facebook Conversations



Disqus Conversations