You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 23:57:03