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

Laravel 8.x关联问题:在HasOne中通过HasMany获取最高出价

Laravel HasOne关联实现:获取已审核的最高出价

我想在Laravel的HasOne关联里复用HasMany关联的筛选逻辑,现有Auction和Bid模型代码如下:

class Auction extends Model
{
    //...
    public function bids(): HasMany
    {
        return $this->hasMany(Bid::class, 'auction_id');
    }

    public function approvedBids(): HasMany
    {
        return $this->bids()->approved();
    }

    public function topBids(): HasMany
    {
        return $this->approvedBids()->orderByDesc('price')->take(10);
    }

    public function topBid(): HasOne
    {
        //return $this->topBids()->firstOfMany(); // 无法正常工作
        //return $this->hasOne(Bid::class, 'auction_id')->ofMany('price','max')->approved(); // 无法正常工作
        //return $this->hasOne(Bid::class, 'auction_id')->approved()->ofMany('price','max'); // 无法正常工作
        //return $this->hasOne(Bid::class, 'auction_id')->ofMany('price', 'max'); // 可运行但不符合预期
    }

}
class Bid extends Model
{
    //...
    public function scopeApproved(Builder $query): Builder
    {
        return $query->where('state', BidState::STATE_APPROVED);
    }
    //...
}

我需要实现topBid()关联,从已审核的出价中获取最高出价的单条记录,但尝试的几种写法均无法正常满足需求。

可行解决方案

方案一:直接整合筛选与ofMany关联

先调用approved作用域过滤已审核出价,再通过ofMany指定取价格最高的记录:

public function topBid(): HasOne
{
    return $this->hasOne(Bid::class, 'auction_id')
        ->approved()
        ->ofMany(
            ['price' => 'max'],
            // 可选:同价时取最新创建的出价
            fn($query) => $query->orderBy('created_at', 'desc')
        );
}

注意顺序:必须先调用筛选作用域,再使用ofMany。如果反过来,筛选条件会被加到外层查询而非聚合子查询中,导致无法正确过滤已审核出价。

方案二:复用已有approvedBids关联逻辑

如果想完全复用approvedBids()的筛选规则,可通过mergeConstraintsFrom合并查询条件:

public function topBid(): HasOne
{
    // 获取approvedBids的查询约束
    $approvedQuery = $this->approvedBids()->getQuery();

    return $this->hasOne(Bid::class, 'auction_id')
        ->mergeConstraintsFrom($approvedQuery)
        ->ofMany('price', 'max');
}

这种方式能确保topBid()和approvedBids()使用完全一致的筛选逻辑,后续修改approvedBids时无需同步修改topBid。

原有写法失败原因

  • $this->topBids()->firstOfMany():topBids()返回的是HasMany实例,firstOfMany只能用于HasOne关联,类型不匹配导致报错。
  • ofMany放在approved()之前:ofMany会生成聚合子查询,此时调用approved()会把筛选条件加到外层查询,无法过滤聚合子查询中的数据,导致结果包含未审核出价。
  • 仅用ofMany('price', 'max'):缺少approved筛选,会返回所有出价中的最高价,不符合需求。

内容的提问来源于stack exchange,提问作者Pejman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 19:55:48