Laravel/Eloquent:遍历包含带已审核评论文章的话题
嘿,我来帮你解决这个Laravel Blade遍历筛选的问题!首先得明确一点:虽然你想直接在Blade的@foreach里用$topics->where(...)实现,但其实更高效的做法是在控制器层面先完成过滤,再把结果传给视图——不过我也会告诉你两种方式的实现方法。
推荐方案:控制器层面提前过滤(性能更优)
直接在Blade里操作集合是内存层面的过滤,会先加载所有话题再筛选,数据量大的时候会拖慢页面。所以最好先在控制器里用Eloquent的whereHas方法,从数据库层面直接筛选出符合条件的话题:
首先确保你的模型关联已经正确定义(如果还没写的话):
- Topic模型:
class Topic extends Model { public function articles() { return $this->hasMany(Article::class); } public function comments() { return $this->hasManyThrough(Comment::class, Article::class); } }
- Article模型:
class Article extends Model { public function topic() { return $this->belongsTo(Topic::class); } public function comments() { return $this->hasMany(Comment::class); } }
- Comment模型:
class Comment extends Model { public function article() { return $this->belongsTo(Article::class); } }
然后在控制器里编写查询:
// 比如在某个控制器方法中 public function index() { $topics = Topic::whereHas('articles.comments', function ($query) { // 筛选出包含已审核评论的文章所属的话题 $query->where('approved', true); })->get(); return view('your-view-name', compact('topics')); }
之后在Blade模板里直接遍历即可:
@foreach($topics as $topic) <div> <h3>{{ $topic->label }}</h3> <!-- 这里可以继续展示该话题下的文章等内容 --> </div> @endforeach
如果你一定要在Blade里直接用集合过滤
如果因为某些原因必须在Blade里操作,你可以利用Eloquent集合的whereHas方法(注意这是集合方法,不是查询构建器,依然是内存过滤):
@foreach($topics->whereHas('articles.comments', function ($query) { $query->where('approved', true); }) as $topic) <div> <h3>{{ $topic->label }}</h3> <!-- 你的展示内容 --> </div> @endforeach
或者用更简洁的箭头函数(PHP 7.4+支持):
@foreach($topics->whereHas('articles.comments', fn($q) => $q->where('approved', true)) as $topic) <!-- 展示内容 --> @endforeach
⚠️ 注意:这种方式会先加载所有$topics数据到内存,再进行过滤,当话题数量较多时,性能会比控制器层面的查询差很多,所以优先推荐第一种方案。
内容的提问来源于stack exchange,提问作者Barret Wallace
相关产品推荐
相关产品推荐

