我在Laravel中有一种情况,我必须在视图中查询关系数据。问题是当我在对象的关系数据上使用Query构建器方法时,正在返回对象的子关系的所有记录。
我有这个时区模型,在使用过滤器查询后,控制器会返回考勤数据。
$timezones->attendances; // Let's say I have queried and returned for all attendances in this timezone with "team_id" = 1
现在在刀片视图中我有类似的东西:
@foreach($timezones as $timezone)
<tr>
<th>{{ $timezone->name }}</th>
@for($day = 1; $day <= $daysInMonth; $day++)
<td>
{{ count($timezone->attendances()->where([["attendance_date",\Carbon\Carbon::parse($defaultYear . '-' . $month->format('m') . '-' . $day)->format('Y-m-d')],['is_ignore',false]])->get()) }}
</td>
@endfor
</tr>
@endforeach
上述解决方案仅返回时区对象的所有出席情况,无论我使用来自我的控制器的where查询应用的过滤器。
$timezones = Timezone::with(['attendances' => function($query) use ($request) {
$query->where('team_id',$request->input('team'));
}])->get();
有关如何在视图文件中实现此功能的任何帮助吗?
答案 0 :(得分:0)
初始查询不起作用的原因是因为当您将关系作为方法调用时,它将返回查询构建器的新实例,而不使用原始查询的缓存结果。此外,在循环中进行查询通常是一个坏主意。
以下内容可以放在您的控制器逻辑中并保存执行大量不必要的查询:
$timezones->map(function ($timezone) use ($defaultYear, $daysInMonth, $month) {
$timezone->attendanceCounts = collect(range(1, $daysInMonth))
->flatMap(function ($day) use ($timezone, $defaultYear, $month) {
$date = Carbon::now()->year($defaultYear)->month($month)->day($day);
return [
$day => $timezone->attendances
->filter(function ($item) use ($date) {
return $item->attendance_date->isSameDay($date) && !$item->is_ignore;
})->count(),
];
});
return $timezone;
});
以上假设attendance_date
被投射到Carbon
Eloquent
实例并且您的控制器中也有$defaultYear, $daysInMonth, $month
。如果attendance_date
不是您可以更改的Carbon
实例:
$item->attendance_date->isSameDay($date)
为:
$item->attendance_date = $date->format('Y-m-d');
然后在您的blade
文件中,您可以:
@foreach($timezones as $timezone)
<tr>
<th>{{ $timezone->name }}</th>
@foreach($timezone->attendanceCounts as $count)
<td>
{{ $count }}
</td>
@endfor
</tr>
@endforeach
有关Collections
的详情,请查看https://laravel.com/docs/5.3/collections
希望这有帮助!