Laravel 5.5关联查询问题:获取用户职位的最新作业单
解决Laravel 5.5中获取用户职位及对应最新作业单的问题
嘿,我明白你现在的困扰——想要拿到当前登录用户的所有职位,每个职位只带最新的那一张作业单,之前的尝试要么返回了所有作业单,要么关联调整没到位。别担心,我给你两种靠谱的实现方式,你可以根据自己的业务场景选:
方法一:通过模型关联定义最新作业单
这种方式最符合Laravel的Eloquent关联风格,代码也更优雅:
在Job模型中新增关联最新作业单的方法
我们用hasOne关联,配合latest()方法来获取每个职位的最新作业单(默认按created_at降序,如果你需要按更新时间排序,改成latest('updated_at')即可):// app/Job.php namespace App; use Illuminate\Database\Eloquent\Model; class Job extends Model { // 其他关联和方法... public function latestJobSheet() { // 这里默认按created_at取最新,可根据业务调整字段 return $this->hasOne(JobSheet::class)->latest(); } }调整User模型的jobs关联,预加载最新作业单
为了避免N+1查询问题,我们在User的jobs关联里直接预加载latestJobSheet:// app/User.php namespace App; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable { use Notifiable; // 其他代码... public function jobs() { return $this->hasMany(Job::class)->with('latestJobSheet'); } }在控制器中获取数据
现在你只需要拿到当前登录用户的jobs,每个job里就会包含latestJobSheet属性,对应最新的作业单:// 控制器方法 public function getUserJobs() { $user = auth()->user(); $jobsWithLatestSheet = $user->jobs; // 后续可以返回视图或者JSON return view('jobs.index', compact('jobsWithLatestSheet')); }
方法二:通过查询构建器直接查询(适合复杂场景)
如果你需要更灵活的查询控制,比如额外筛选作业单字段,可以用子查询关联的方式:
// 控制器方法中直接构建查询 use Illuminate\Support\Facades\DB; public function getUserJobs() { $jobs = auth()->user()->jobs() ->leftJoinSub( // 子查询:按job_id分组,获取每个职位的最新作业单ID JobSheet::select('job_id', DB::raw('MAX(id) as latest_sheet_id')) ->groupBy('job_id'), 'latest_sheets', 'jobs.id', '=', 'latest_sheets.job_id' ) // 关联作业单表,拿到最新作业单的详情 ->leftJoin('job_sheets', 'latest_sheets.latest_sheet_id', '=', 'job_sheets.id') // 按需选择字段,注意避免jobs和job_sheets的字段名冲突 ->select('jobs.*', 'job_sheets.id as sheet_id', 'job_sheets.content', 'job_sheets.created_at as sheet_created_at') ->get(); return view('jobs.index', compact('jobs')); }
为什么之前的尝试没成功?
你之前可能直接用了with('jobSheets'),这种关联会加载该职位下的所有作业单;而我们上面用hasOne+latest()的组合,本质是告诉Eloquent:每个职位只关联一条最新的作业单,这样就不会返回所有数据了。
内容的提问来源于stack exchange,提问作者Dev.W
相关产品推荐
相关产品推荐

