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
相关产品推荐
相关产品推荐

