Это не самое оптимальное решение, но оно должно работать.
Сначала получите идентификаторы Video
моделей из объекта разбивки на страницы:
$ids = $videos->getCollection()->pluck('id');
Затем используйте их, чтобы присоединиться к другим таблицам, группируя по видео и выбирая ID с наивысшим рейтингом. Возможно, вам придется настроить это, если у вас есть другие столбцы в вашей рейтинговой таблице, то есть вы можете ранжировать их лучше, чем с помощью их первичного ключа.
$videoToRatingMap = Videos::query()
->whereIn('id', $ids)
->join('episodes', 'episodes.video_id', '=', 'videos.id')
->join('comments', 'comments.episode_id ', '=', 'episodes.id')
->join('ratings', 'ratings.id', '=', 'comments.rating_id')
->groupBy('videos.id')
->select('videos.id')
->selectRaw('max(ratings.id) as rating_id')
->get();
Это даст вам карту видео по идентификатору и комментарий с наивысшим рейтингом.
Это не даст вам названия рейтингов, однако это можно сделать в отдельном запросе:
$ratingNames = Rating::query()
->findMany($videoToRatingMap->pluck('rating_id'))
->pluck('name', 'id');
Затем преобразуйте карту рейтинга, чтобы включить names:
$videoToRatingMap->transform(function($video) use ($ratingNames){
$video['rating_name'] = $ratingNames[$video['rating_id']];
return $video;
})->keyBy('id');
Это даст вам коллекцию, привязанную к идентификаторам видео, которая также содержит идентификатор рейтинга и его имя.
Чуть более оптимальный способ сделать это - взять первый запрос и оберните все это в подзапрос, чтобы вы могли снова присоединиться к таблице рейтингов по нему и получить имя. Сократит количество запросов на один за счет усложнения отдельного запроса.