I have the following queries in my controller to show some statistics about orders paid, and unpaid and the respective amounts (totals), by year. Yet, I feel that the queries I’m using may be optimized but I can’t figure out a better way to do it. Here’s what I have:
public function index(Order $order)
{
$orders = Order::all()->groupBy(function ($order) {
return $order->created_at->format('Y');
})->map(function ($year) {
return $year->sum('total');
});
$unpaid_orders = Order::all()->where('payment_confirmed', 0)->groupBy(function ($order) {
return $order->created_at->format('Y');
})->map(function ($year) {
return $year->sum('total');
});
$paid_orders = Order::all()->where('payment_confirmed', 1)->groupBy(function ($order) {
return $order->payment_confirmed == false ? $order->year : $order->created_at->format('Y');
})->map(function ($year) {
return $year->sum('total');
});
return view('orders.index', compact('orders', 'unpaid_orders', 'paid_orders'));
}
Above I’m querying the Order model three times which it seems that could be optimized.
2
Answers
Do
$collection = Order::all();
once and use$collection
wherever you need it.To optimize the query in the provided code using scopes, you can define scopes in your Order model. Scopes allow you to encapsulate reusable query logic, making it easier to optimize and maintain your code. Here’s an optimized version of the code using scopes:
First, let’s define the scopes in your Order model:
Now, let’s modify the index method to utilize these scopes:
By using scopes, we can chain the necessary conditions and group by logic directly on the Order model, resulting in cleaner and more optimized code.