Laravel Eloquent多对多关联如何用whereHas按pivot表created_at排序
Laravel多对多关联pivot表字段排序解决方案
失效原因
whereHas() 闭包内的orderBy仅作用于关联存在性校验的子查询,不会对外部User主查询的结果集生效,因此你的现有代码只能过滤符合条件的用户,无法按订阅时间排序。
前置准备
先确认User模型的多对多关联已正确声明pivot字段:
// App\Models\User.php public function subscriptions() { return $this->belongsToMany(Event::class, 'subscriptions') ->withPivot('created_at', 'updated_at') ->withTimestamps(); }
方案1:从事件模型侧查询(更简洁,无join)
如果不需要强制从User模型发起查询,直接从指定Event的关联用户查询是最优解,天然支持pivot字段排序:
return Event::findOrFail($eventId) ->users() ->orderBy('subscriptions.created_at', 'ASC') ->paginate(5);
方案2:基于whereHas实现(满足指定用法要求,无join)
如果必须以User为主查询用whereHas实现,可通过子查询实现排序:
return $this->user ->with(['subscriptions' => function ($query) use ($eventId) { $query->where('events.id', $eventId); }]) ->whereHas('subscriptions', function ($query) use ($eventId) { $query->where('events.id', $eventId); }) ->orderBy(fn ($query) => $query ->select('created_at') ->from('subscriptions') ->whereColumn('subscriptions.user_id', 'users.id') ->where('subscriptions.event_id', $eventId) ->limit(1) , 'ASC') ->paginate(5);
两种方案都不需要手动写join,都可以实现按订阅时间升序返回用户列表,且支持分页功能。
内容的提问来源于stack exchange,提问作者Jérémie Chazelle
相关产品推荐
相关产品推荐

