Laravel — нетерпеливая загрузка

Я пытаюсь понять Eager Loading с помощью Laravel, чтобы не создавать много ненужных запросов. Я хочу получить 15 последних добавленных сообщений, а также получить их оценки из отношения моей таблицы ставок (до того, как я получал сообщения, а позже в foreach я вызывал $item->avgRate(), который создает 15 дополнительных запросов: S).

Моя модель поста:

public function rates()
{
    return $this->hasMany(Rate::class);
}

public function scopeLastAdded($query, $limit = 15)
{
    return $query->latest()->limit($limit)->with('rates')->get();
}

Это работает, для каждого сообщения я также получаю все оценки, но основная цель состоит в том, чтобы сделать некоторую функцию для расчета средней скорости для каждого сообщения, а не получать все оценки. Я создал новый метод:

public function avgRate()
{
    return number_format($this->rates()->avg('rate'), 1, '.', '');
}

Когда я использую with('avgRate'), моя модель дает сбой:

Call to a member function addEagerConstraints() on string

Как я могу получить avgRate каким-то чистым способом с моими последними 15 сообщениями, чтобы выполнять только 2 запроса, а не 16?

Ожидаемый результат:

// Post view
@foreach ($posts as $post)
   <div>{{ $post->title }}</div>
   <div>{{ $post->avgRate }}</div> //I want to get data without performing 15 queries
@endforeach
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
132
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я бы использовал подзапрос для достижения этой цели. Кроме того, чтобы сделать вещи немного чище, вы можете создать область для получения рейтинга:

public function scopeWithRating($query)
{
    $rating = Rate::selectRaw('AVG(rate)')
        ->whereColumn('post_id', 'posts.id')
        ->getQuery();

    $query->select('posts.*')
        ->selectSub($rating, 'rating');
}

... и чтобы использовать его, вы должны сделать:

Post::withRating()->get(); 

Теперь ваши объекты Post также будут содержать столбец rating, и это было сделано, по сути, с помощью одного запроса.

Вот пример, чтобы проиллюстрировать это.

Спасибо, @Mozammil, мне нравится твоя идея, кажется ясной. Попробую!

Steve 29.01.2019 20:05

Другие вопросы по теме