Laravel Eager Loading, только когда доступны идентификаторы

У меня есть такая таблица:

payments
   -id
   -client_id
   -vendor_id
   -product_id
   -item_id
   -..._id

Используя нетерпеливую загрузку Laravel, я могу сделать это ->load('client', 'vendor' ... ) и загрузить отношения для всех возвращенных строк payments. Но я заметил, что, например, когда в payments для vendor_id нет значений, нетерпеливый запрос загрузки для отношения «поставщик» все еще происходит, как показано ниже:

select * from `vendors` where `vendors`.`id` in ('')

Я понимаю, что in ('') должно быть заполнено значениями для vendor_id в таблице payments, но, поскольку их не было, вышеуказанный запрос не должен выполняться, верно?! Это ошибка в Laravel?

Проблема в том, что я получил около 20 [x]_id столбцов в этой payments таблице, и в каждой строке только пара (варьируется для каждой строки) [x]_id столбцов имеют значения, и я не хочу делать 20 лишних запросов с нетерпеливой загрузкой, просто те, которые необходимы на основе фактического существования этих идентификаторов!

Это не похоже на ошибку, но, безусловно, это то, что можно оптимизировать. Я бы предложил сделать пул реквест или проблему на репозиторий фреймворка Laravel.

Jerodev 20.02.2019 09:58

Какая у вас точная версия Laravel?

Jonas Staudenmeir 20.02.2019 10:27

Какая у вас версия? Что-нибудь >= 4.2.17 уже должно переводить пустое предложение where в "0=1".

patricus 20.02.2019 10:30

Я использую Laravel 5.5!

Dewan159 20.02.2019 10:31

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

Jonas Staudenmeir 20.02.2019 10:41

@JonasStaudenmeir Я думаю, вы уже исправили это для быстрой загрузки: PR объединен в 5.7.20 . Но это не сильно помогает OP на 5.5. Просто дает ему надежду на будущее. :)

patricus 20.02.2019 10:54

@patricus Запрос с предложением where 0 = 1 должен быть довольно быстрым, но он все равно выполняется, когда в этом нет необходимости.

Jonas Staudenmeir 20.02.2019 10:59

@JonasStaudenmeir Да. Мой первоначальный комментарий просто напоминал о том, что в нем используются ярлыки для пустых массивов. Когда я проверил отношения и увидел, что это не так, именно тогда я зашел в код, чтобы найти проблему, а затем проверил, исправлена ​​ли она, и нашел ваши PR. Что касается решения для ОП, то делать нечего, кроме как обновить, и, к сожалению, это не очень полезный ответ. :(

patricus 20.02.2019 11:06
Стоит ли изучать 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 и хотите разрабатывать...
0
8
771
1

Ответы 1

Когда вы выполняете lazy нетерпеливую загрузку, laravel не знает, присутствуют записи или нет. Если нет, laravel возвращает пустую коллекцию.

Если вы хотите отфильтровать в самом начале, чтобы отображались только платежи с поставщиками, клиентами и т. д., вы можете сделать:

$payments : Payment::whereHas('vendors')->whereHas('clients')->get();

Выше вы получите только платежи, которые содержат хотя бы одного поставщика и 1 клиента.

Кроме того, вы используете load(), что означает ленивую загрузку. Он разработан таким образом, что вы можете сначала получить основную коллекцию, а затем, когда и если вам нужно, получить только коллекцию отношений.

Отметьте with(), если вы не хотите лениво загружаться.

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

На самом деле я использую with() в приведенной выше ситуации.

Dewan159 20.02.2019 11:18

Я считаю, что вам действительно нужно использовать with()рядомwhereHas(), чтобы и с нетерпением загружал только модели с такими отношениями.

brad 21.02.2019 11:11

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