Laravel 10:如何通过Has Many Through获取分类最新单条帖子
解决方案
你可以通过以下几种方式实现每个分类仅加载最新一条ForumPost:
方法一:定义专属关联方法(推荐)
在ForumCategory模型中新增一个用于获取最新帖子的关联,利用hasOneThrough结合排序与限制:
use Illuminate\Database\Eloquent\Relations\HasOneThrough; public function latestPost(): HasOneThrough { return $this->hasOneThrough( ForumPost::class, ForumThread::class )->latest('forum_posts.created_at')->limit(1); }
查询时直接加载该关联及作者信息即可:
$categories = ForumCategory::with('latestPost.author')->get();
每个分类的latestPost属性会直接对应其最新帖子模型,不会加载所有关联帖子。
方法二:在关联查询中通过子筛选限制结果
如果不想新增关联方法,可修改原with闭包,通过子查询筛选每个分类的最新帖子ID:
use Illuminate\Support\Facades\DB; $categories = ForumCategory::with(['posts' => function ($q) { $q->with('author') ->whereIn('forum_posts.id', function ($subQuery) { $subQuery->select(DB::raw('MAX(fp.id)')) ->from('forum_posts as fp') ->join('forum_threads as ft', 'fp.forum_thread_id', '=', 'ft.id') ->groupBy('ft.forum_category_id'); }); }])->get();
注:若帖子的
created_at比自增ID更适合判断"最新",可将MAX(fp.id)替换为MAX(fp.created_at),同时外层查询需匹配created_at字段(需确保每个分类下最新帖子的created_at唯一,否则可能返回多条结果)。
方法三:使用子查询自定义关联
在ForumCategory模型中定义直接关联到最新帖子的逻辑:
public function latestPost() { return $this->hasOne(ForumPost::class) ->join('forum_threads', 'forum_posts.forum_thread_id', '=', 'forum_threads.id') ->whereColumn('forum_threads.forum_category_id', 'forum_categories.id') ->latest('forum_posts.created_at'); }
查询方式与方法一一致:
$categories = ForumCategory::with('latestPost.author')->get();
内容的提问来源于stack exchange,提问作者Klick
相关产品推荐
相关产品推荐

