Refactoring with Computed Properties Package

Nikita Tolkachev
Aug 22, 2017 · 2 min read

Today I’ve released https://github.com/n7olkachev/laravel-computed-properties which is based on this tweet:

So, why is it so cool and what’s the difference between a computed property and a default accessors (getFooBarAttribute)?

Consider next example. We have Order and OrderProduct . OrderProduct has price and count fields. Sum of an order is sum of price * count of all its products.

If you want to compute sum of an order you will write something like this:

public function getSumAttribute()
{
return $this->products->sum(function ($product) {
return $product->price * $product->count;
});
}

Nice! We can use $order->sum now.

Time passes, new tasks come. Your manager says that you need to show orders with sum > 50 in a dashboard.

Ooops! You can’t just use your accessor, because it works with a model instance, not a query. You can create something like scopeWithSum which will make a sub-select for you, but it won’t be pretty at all. Also, it will lead to code duplication.

This is a perfect example of the power of https://github.com/n7olkachev/laravel-computed-properties

Instead of getSumAttribute lets write computedSum method.

public function computedSum($order)
{
$selectSum = new Expression('sum(price * count)');
return OrderProduct::select($selectSum)
->where('order_id', $order->id);
}

All of your $order->sum calls continue to work, but there is more! Now, you can use sum field in your queries!

Order::withComputed('sum')->having('sum', '>', 50)->get()

That’s it! Your task is closed, without any code duplication and ugly scope magic.

)

Nikita Tolkachev

Written by

Developer at https://websecret.by/

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade