Laravel中如何基于work type的foreignId二次筛选关联表内容?
问题描述
现有pekerjaan(工作)与jeniskerja(工作类型)两张表,Eloquent关联关系为:jeniskerja hasMany pekerjaan、pekerjaan belongsTo jeniskerja。目前已通过penyedia(供应商)的外键展示对应工作列表,需实现点击工作类型卡片标题时,展开并展示该类型下的工作列表。
当前代码如下:
控制器代码(AdminController)
public function showpenyedia(Penyedia $penyedia){ $pekerjaan = $penyedia->pekerjaans; // 根据供应商展示对应工作 $jeniskerja = Jeniskerja::all(); return view('admin.showpenyedia', compact('penyedia','pekerjaan','jeniskerja')); }
视图代码(detailpenyedia.php)
@foreach ($jeniskerja as $jeniskerjas) <section class="content"> <div class="container-fluid"> <div class="card card-default collapsed-card"> <div class="card-header collapsed-card"> <h3 class="card-title"> <b>{{$jeniskerjas->nama_jenis}}</b> <!-- 显示工作类型名称 --> </h3> <div class="card-tools"> <button type="button" class="btn btn-tool" data-card-widget="collapse"> <i class="fas fa-plus"></i> </button> </div> </div> <div class="card-body table-responsive"> <table id="tabelpekerjaan" class="table table-bordered"> <thead> <tr> <th style="width: 10px" rowspan="2">年度预算</th> <th rowspan="2">合同日期</th> <th rowspan="2">工作包</th> <th rowspan="2">公司名称</th> <th rowspan="2">工作地点</th> <th rowspan="2">工作类型</th> <th rowspan="2">HPS</th> <th rowspan="2">金额</th> <th rowspan="2">文档</th> <th colspan="2">日期</th> </tr> <tr> <td>创建日期</td> <td>更新日期</td> </tr> </thead> <tbody> @php $no = 1; /*$totalNilai = 0.0;*/ @endphp @foreach ($pekerjaan as $pekerjaans) <tr> <td>{{$pekerjaans->tanggal->format('Y')}}</td> <td>{{$pekerjaans->tanggal->format('d/m/Y')}}</td> <td>{{$pekerjaans->pekerjaan}}</td> <td>{{$pekerjaans->penyedia->nama}}</td> <td>{{$pekerjaans->lokasi}}</td> <td>{{$pekerjaans->jeniskerja->nama_jenis}}</td> <td>Rp. {{number_format($pekerjaans->hps,0,',',',')}}</td> @php $pekerjaans->nilai_total = $pekerjaans->nilai_1 + $pekerjaans->nilai_2 + $pekerjaans->nilai_3 + $pekerjaans->nilai_4; @endphp <td>{{$pekerjaans->nilai_total}}</td> <td><a href="{{ route('pekerjaans.download', $pekerjaans->id) }}"><u>{{$pekerjaans->status}}</u></a></td> <td></td> <td></td> </tr> @endforeach </tbody> </table> </div> </div> </div> </section> @endforeach
解决方法
1. 优化控制器查询逻辑
修改控制器,预加载每个工作类型下属于当前供应商的工作,避免N+1查询,同时减少不必要的数据传递:
public function showpenyedia(Penyedia $penyedia){ // 预加载工作类型,并筛选出当前供应商的对应工作 $jeniskerja = Jeniskerja::with(['pekerjaans' => function($query) use ($penyedia) { $query->where('penyedia_id', $penyedia->id); }])->get(); return view('admin.showpenyedia', compact('penyedia','jeniskerja')); }
2. 调整视图展示逻辑
修改视图,让每个工作类型卡片只展示该类型下的工作,同时优化折叠组件行为:
@foreach ($jeniskerja as $jeniskerjaItem) <section class="content"> <div class="container-fluid"> {{-- 只显示有对应工作的类型卡片 --}} @if($jeniskerjaItem->pekerjaans->isNotEmpty()) <div class="card card-default collapsed-card"> <div class="card-header" data-card-widget="collapse"> <h3 class="card-title"> <b>{{$jeniskerjaItem->nama_jenis}}</b> {{-- 添加工作数量徽章 --}} <span class="badge bg-primary ml-2">{{$jeniskerjaItem->pekerjaans->count()}}</span> </h3> <div class="card-tools"> <button type="button" class="btn btn-tool"> <i class="fas fa-plus"></i> </button> </div> </div> <div class="card-body table-responsive"> <table class="table table-bordered"> <thead> <tr> <th style="width: 10px" rowspan="2">年度预算</th> <th rowspan="2">合同日期</th> <th rowspan="2">工作包</th> <th rowspan="2">公司名称</th> <th rowspan="2">工作地点</th> <th rowspan="2">工作类型</th> <th rowspan="2">HPS</th> <th rowspan="2">总金额</th> <th rowspan="2">文档</th> <th colspan="2">日期</th> </tr> <tr> <td>创建日期</td> <td>更新日期</td> </tr> </thead> <tbody> @php $no = 1; @endphp @foreach ($jeniskerjaItem->pekerjaans as $pekerjaan) <tr> <td>{{$pekerjaan->tanggal->format('Y')}}</td> <td>{{$pekerjaan->tanggal->format('d/m/Y')}}</td> <td>{{$pekerjaan->pekerjaan}}</td> <td>{{$pekerjaan->penyedia->nama}}</td> <td>{{$pekerjaan->lokasi}}</td> <td>{{$pekerjaan->jeniskerja->nama_jenis}}</td> <td>Rp. {{number_format($pekerjaan->hps,0,',',',')}}</td> @php $totalNilai = $pekerjaan->nilai_1 + $pekerjaan->nilai_2 + $pekerjaan->nilai_3 + $pekerjaan->nilai_4; @endphp <td>{{$totalNilai}}</td> <td><a href="{{ route('pekerjaans.download', $pekerjaan->id) }}"><u>{{$pekerjaan->status}}</u></a></td> <td>{{$pekerjaan->created_at->format('d/m/Y')}}</td> <td>{{$pekerjaan->updated_at->format('d/m/Y')}}</td> </tr> @endforeach </tbody> </table> </div> </div> @endif </div> </section> @endforeach
关键调整说明
- 移除
card-header上重复的collapsed-card类,确保Bootstrap折叠组件正常触发 - 添加工作数量徽章,提升用户体验
- 过滤无对应工作的类型卡片,避免空卡片占用空间
- 补全创建/更新日期的显示逻辑
- 优化变量命名,提升代码可读性
内容的提问来源于stack exchange,提问作者YuPi
相关产品推荐
相关产品推荐

