You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

修复方案

问题根源

  1. Controller里的循环每次都会覆盖oneemployee变量,最终只保留了最后一条工时记录对应的员工数据,导致所有行都显示同一个姓名。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 03:50:17