I reckon you want to get all the books with the ratings by the specified user only. You might want to try constraining eager loading:
Book::with([
'images',
'ratings' => function ($query) {
$query->where('user_id', $this->user_id);
}])
->join('collections as c', 'c.book_id', '=', 'books.id')
->where('c.user_id', '=', $this->user->id)
->paginate(20)
// Or this might also work.
Book::with([
'images',
'ratings' => fn ($query) => $query->where('user_id', $this->user_id)
])
->join('collections as c', 'c.book_id', '=', 'books.id')
->where('c.user_id', '=', $this->user->id)
->paginate(20)
By the way, though joining tables can be more performant, it would be a bit cleaner to create a relationship and a query scope.
class Book extends Model
{
public function collectedByUsers()
{
return $this->belongsToMany(User::class, 'collections');
}
public function scopeCollectedBy($query, User $user)
{
return $query->whereRelation('collectedByUsers', 'id', '=', $user->id );
}
}
class Rating extends Model
{
public function scopeRatedBy($query, User $user)
{
return $query->where('user_id', $user->id);
}
}
So you can simply do this:
Book::with([
'images',
'ratings' => function ($query) {
$query->ratedBy($this->user);
}])
->collectedBy($this->user)
->paginate(20)