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

Laravel中在Scope内调用关联方法报错的问题求助

解决Laravel Scope中调用关联方法报错的问题

错误原因

你遇到的Call to undefined method Illuminate\Database\Eloquent\Builder::members()错误,是因为在Book模型的Scope里直接调用了members()关联方法——Scope接收的$query参数是Book模型的查询构建器实例,而members()是Book模型本身的关联方法,只能在Book模型实例上调用,不能直接用在Builder上。

解决方案

根据你的需求(从单本Book实例获取当前借出的会员),有两种更合理的实现方式:

方式一:直接使用关联查询(推荐)

先确保Book模型中正确定义了与Member的关联,包含中间表的字段:

// Book模型
public function members()
{
    return $this->belongsToMany(Member::class, 'book_member')
                ->withPivot('return_date', 'returned');
}

然后修改控制器代码,直接通过关联查询筛选:

$members = $book->members()
                ->wherePivot('returned', false)
                ->orderBy('return_date')
                ->paginate(8);

方式二:封装为模型方法(替代Scope)

如果想把筛选逻辑封装起来,不要用Scope(Scope的设计目的是约束当前模型的查询,而非获取关联模型),而是写一个普通的模型方法:

// Book模型
public function loanedMembers()
{
    return $this->members()
                ->wherePivot('returned', false)
                ->orderBy('return_date');
}

控制器中调用这个方法:

$members = $book->loanedMembers()->paginate(8);

额外说明

如果你想用Scope实现的是筛选出存在未归还会员的书籍(而非从单本书获取会员),可以这样写Scope:

// Book模型
public function scopeHasLoanedMembers(Builder $query): Builder
{
    return $query->whereHas('members', function ($subQuery) {
        $subQuery->wherePivot('returned', false);
    });
}

使用时:

// 获取所有有未归还记录的书籍
$books = Book::hasLoanedMembers()->get();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 22:10:35