Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

KrayRish's avatar

Calculated Fields

Hello wonderful Laracasts community,

I'm just starting out my Laravel journey, and have a small project I'm using to consolidate the basics. I'm a bit confused about where/how I deal with calculated fields and Eloquent models. I have a model where I initially put all the properties in the database, but then realised that I didn't actually want the user to input half of them since many are calculated.

So my question, is the model the right place to keep calculated fields (and if so, do I just add them as attributes to the model?) or should I use some other abstraction to separate out the logic from the model?

0 likes
6 replies
acasar's avatar

You can use accessors. In Eloquent it's very simple - you can just add methods named "get[Name]Attribute", where [Name] equals to the name of the calculated attribute.

For example, if you store user's bithday in the database, you can add an accessor to get his age:

protected $dates = ['birthday']; // this tells Eloquent to cast "birthday" attribute into a Carbon instance

public function getAgeAttribute() {
    return $this->birthday->age;
}

Now you can use it as a normal attribute:

echo "User's age: " . $user->age;
4 likes
blonkm's avatar

What if the calculation is expensive and you want to cache it, but not persist it? You obviously don't need your calculated fields in the database. What are the options?

EliasSoares's avatar

@blonkm

So use Cache! Laravel implements many cache drivers that are very easy to use like: Cache::put ('model.434.age', $calculated_age)

Also you have Cache::remember () that allow you passing a callback to define the cache value if not cache yet.

Take a look at docs!

1 like
riddhi's avatar

Can this calculated attribute be used is queries. Can I write something like User::where('age', ' > ', 100)

1 like
beakerflo's avatar

You could do this if you use the methods on the collection. https://laravel.com/docs/5.3/eloquent-collections#available-methods

for example; `$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100], ['product' => 'Bookcase', 'price' => 150], ['product' => 'Door', 'price' => 100], ]);

$filtered = $collection->where('price', 100);

$filtered->all();

/* [ ['product' => 'Chair', 'price' => 100], ['product' => 'Door', 'price' => 100], ] */`

siar_1stLocateLeeds's avatar

You can specify your calculated field in your select as follows:

$model->select(['*', \DB::raw('(initialAmount+interest-(writeOffs+credits+paid+leftOver)) AS balance')]);

Please or to participate in this conversation.