如何按关联最后任务的日期对Laravel中的Project模型数据排序?
解决方案
1. 优化查询逻辑,实现按最新任务日期排序
直接在控制器中通过Laravel的withMax方法获取每个项目最新任务的创建时间,同时按该字段排序,还能保留任务数量统计:
public function index() { $projects = Project::withCount('tasks') ->withMax('tasks', 'created_at') // 自动生成字段`tasks_max_created_at`,存储对应项目最新任务的创建时间 ->orderByDesc('tasks_max_created_at') // 按最新任务日期降序排列,升序替换为`orderBy`即可 ->get(); return view('project.index', compact('projects')); }
2. 修复视图的N+1查询问题与语法错误
原视图中每次循环调用$project->tasks()->latest()->first()会触发额外数据库查询,造成N+1性能问题,同时代码里存在多余的</a>标签,修改后直接使用预加载的字段:
<table id="tabledata"> <thead> <tr> <th></th> <th>Title</th> <th>Name</th> <th>Date last task</th> <th>N. Tasks</th> </tr> </thead> <tbody> @foreach ($projects as $project) <tr> <td></td> <td class="p-4">{{ $project->title }}</td> <td class="p-4">{{ $project->name }}</td> <td class="p-4"> {{ $project->tasks_max_created_at ? \Carbon\Carbon::parse($project->tasks_max_created_at)->format('d/m/Y') : '无任务' }} </td> <td class="text-center">{{ $project->tasks_count }}</td> </tr> @endforeach </tbody> </table>
3. 可选:获取完整的最新任务对象(如需更多字段)
如果除了日期还需要访问最新任务的其他属性,可以在Project模型中添加专属关联:
class Project extends Model { use HasFactory; protected $fillable = [ 'title', 'name', ]; public function tasks() { return $this->hasMany(Task::class); } public function latestTask() { return $this->hasOne(Task::class)->latest(); } }
控制器中预加载该关联并排序:
$projects = Project::withCount('tasks') ->with('latestTask') ->orderByDesc('latestTask.created_at') ->get();
视图中即可直接调用任务对象的属性:
<td class="p-4"> {{ $project->latestTask ? $project->latestTask->created_at->format('d/m/Y') : '无任务' }} </td>
注意点
- 对无任务的项目要做空值判断,避免出现调用
created_at的报错 withMax是最轻量化的实现方式,仅获取日期字段;若需完整任务数据,再使用latestTask关联
内容的提问来源于stack exchange,提问作者Sarah
相关产品推荐
相关产品推荐

