Отношение Eloquent «один ко многим»: запрос для фильтрации на основе значений столбца связанной таблицы

У меня есть две таблицы, которые выглядят так:

stocks:

id | name      | market_cap
1  | Microsoft | 5000
2  | Tesla     | 2000

Эта таблица имеет связь «один ко многим» с таблицей под названием stock_ratings:

id | stock_id | measure | value
12 | 1        | revenue | 30
13 | 1        | dividend| 5
14 | 2        | revenue | 10
15 | 2        | dividend| 0

Теперь предположим, что пользователь хочет получить все акции с помощью market_cap > 3000, пропустить первые 20 результатов и получить следующие 20. Это работает:

$query = Stock::where('market_cap', '>', 3000);
$stocks = $query->skip(20)->take(20)->get();

Однако пользователь также должен иметь возможность запрашивать данные stock_ratings. Итак, скажем, в дополнение к указанным выше условиям он хочет найти все акции, которые имеют value > 20 для меры revenue.

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

$query = Stock::where('market_cap', '>', 3000);
$query = $query->with(['ratings' => function ($q) {
    $q->where('stock_ratings.measure', 'revenue');
    $q->where('stock_ratings.value', '>', 0);
}]);
$stocks = $query->skip(20)->take(20)->get();

Это возвращает все акции с market_cap > 3000 независимо от value и measure в таблице stock_ratings. Он возвращает акции, которые имеют отрицательное значение value в stock_ratings, где measure = revenue, а также строки, которые вообще не имеют связанных строк в stock_ratings.

Как решить эту проблему?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать 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 и хотите разрабатывать...
2
0
304
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Когда вы применяете ограничение в with, это означает, что применяется ограничение, для которых вложенные связанные записи должны быть загружены, а какие нет.

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

Так что попробуй это

$query = Stock::where('market_cap', '>', 3000);

$query = $query->whereHas('ratings', function ($q) {
    $q->where('measure', 'revenue');
    $q->where('value', '>', 0);
})-with('ratings');

$stocks = $query->skip(20)->take(20)->get();

Подробнее читайте в документации Laravel: https://laravel.com/docs/8.x/eloquent-relationships#querying-relationship-existence

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