Laravel多表关联问题:Timesheet与Employees姓名匹配错误修复
问题描述
我有employees和timesheets两张数据表,期望查询结果里不同ID对应正确的员工姓名,但当前所有条目都显示同一个姓名。以下是相关代码,求修复方案。
Controller 代码
$profile = ['no' => Auth::user()->no]; $timesheets = Timesheet::where($profile)->select('*')->orderBy('created_at','DESC')->get(); foreach ($timesheets as $employee) { $emp = ['identification' => $employee->identification]; $oneemployee = Employees::where($emp)->select('*')->orderBy('created_at','DESC')->get(); } return view('contractor.employees.timesheets', compact('timesheets', 'oneemployee'));
Blade 模板代码
@foreach ($timesheets as $row1) <tr> <td>#</td> @foreach ($oneemployee as $row2) <td>{{ $row2->fname}}</td> <td>{{ $row2->lname}}</td> @endforeach <td>{{ $row1->identification}}</td> <td>{{ $row1->week}}</td> <td>{{ $row1->year}}</td> </tr> @endforeach
修复方案
问题根源
- Controller里的循环每次都会覆盖
oneemployee变量,最终只保留了最后一条工时记录对应的员工数据,导致所有行都显示同一个姓名。 - Blade模板里嵌套遍历
oneemployee集合,会重复输出姓名,逻辑完全错误。
方案1:用Eloquent关联(推荐,性能更好)
先给Timesheet模型添加关联关系:
// 在Timesheet模型文件中 public function employee() { // 第二个参数是timesheets表的外键,第三个是employees表的关联字段 return $this->belongsTo(Employees::class, 'identification', 'identification'); }
然后修改Controller,预加载关联数据,避免多次查询数据库:
$profile = ['no' => Auth::user()->no]; // 用with预加载employee关联,一次性拉取所有需要的员工数据 $timesheets = Timesheet::where($profile) ->with('employee') ->orderBy('created_at','DESC') ->get(); return view('contractor.employees.timesheets', compact('timesheets'));
最后简化Blade模板,直接通过关联获取员工姓名:
@foreach ($timesheets as $timesheet) <tr> <td>#</td> <!-- 用??处理员工不存在的情况,避免报错 --> <td>{{ $timesheet->employee->fname ?? '无数据' }}</td> <td>{{ $timesheet->employee->lname ?? '无数据' }}</td> <td>{{ $timesheet->identification}}</td> <td>{{ $timesheet->week}}</td> <td>{{ $timesheet->year}}</td> </tr> @endforeach
方案2:不使用关联,调整原代码逻辑
如果不想用模型关联,可以修改Controller,把员工数据绑定到每条工时记录上:
$profile = ['no' => Auth::user()->no]; $timesheets = Timesheet::where($profile)->orderBy('created_at','DESC')->get(); // 给每条工时记录添加employee属性 foreach ($timesheets as $timesheet) { // 用first()而不是get(),因为一个identification对应一个员工 $timesheet->employee = Employees::where('identification', $timesheet->identification)->first(); } return view('contractor.employees.timesheets', compact('timesheets'));
Blade模板和方案1的写法一致即可,不需要嵌套循环。
内容的提问来源于stack exchange,提问作者Daniel C
相关产品推荐
相关产品推荐

