I am using a query to fetch data from the database. after fetching I am adding one extra attribute to each object but for that i have to use three foreach loop I want to avoid that foreach loop. How I can do this
here is my code for query
$invoices = Invoice::when(!empty($request->customer_id), function ($q) use ($request) {
return $q->where('customer_id', $request->customer_id);
})->where('start_date', '>=', $request->start_date)->whereDate('end_date', '<=', $request->end_date)->when(!empty($request->rate_zone_id), function ($q) use ($request) {
$q->whereHas('consignments_invoices.charges', function ($query) use ($request) {
$query->where('rate_zone_id', $request->rate_zone_id);
});
})->withCount(['consignments_invoices'])->with(['customers:id,name', 'invoice_totals', 'consignments_invoices.charges'])->get();
Here I am adding one more attribute in object with help of foreach loop
foreach ($invoices as $invoice) {
$invoice->setAttribute('rate_zone_income','');
if (!empty($request->rate_zone_id)) {
$rate_zone_income = 0;
foreach ($invoice->consignments_invoices as $consignment) {
foreach ($consignment->charges as $charge) {
if ($charge->rate_zone_id == $request->rate_zone_id) {
$rate_zone_income += $charge->income;
}
}
}
$invoice->setAttribute('rate_zone_income',$rate_zone_income);
}
}
Why not using accessors:
class Invoice extends Model
{
// ...
public function getRateZoneIncomeAttribute($rateZoneId = null)
{
if (empty($rateZoneId)) {
return '';
}
return $invoice->consignments_invoices->reduce(function($rate_zone_income, $consignment) {
return $cosignment->charges->reduce(function($rate_zone_income, $charge) {
if ($charge->rate_zone_id == $rateZoneId) {
$rate_zone_income += $charge->income;
}
return $rate_zone_income;
}, $rate_zone_income);
}, 0);
}
// ...
}