Refactoring with Computed Properties Package

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.
