У меня есть такая таблица:
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?
Какая у вас версия? Что-нибудь >= 4.2.17 уже должно переводить пустое предложение where в "0=1".
Я использую Laravel 5.5!
Это было фиксированный для отложенной загрузки, но не для активной загрузки. Я посмотрю на это.
@JonasStaudenmeir Я думаю, вы уже исправили это для быстрой загрузки: PR объединен в 5.7.20 . Но это не сильно помогает OP на 5.5. Просто дает ему надежду на будущее. :)
@patricus Запрос с предложением where 0 = 1 должен быть довольно быстрым, но он все равно выполняется, когда в этом нет необходимости.
@JonasStaudenmeir Да. Мой первоначальный комментарий просто напоминал о том, что в нем используются ярлыки для пустых массивов. Когда я проверил отношения и увидел, что это не так, именно тогда я зашел в код, чтобы найти проблему, а затем проверил, исправлена ли она, и нашел ваши PR. Что касается решения для ОП, то делать нечего, кроме как обновить, и, к сожалению, это не очень полезный ответ. :(






Когда вы выполняете lazy нетерпеливую загрузку, laravel не знает, присутствуют записи или нет. Если нет, laravel возвращает пустую коллекцию.
Если вы хотите отфильтровать в самом начале, чтобы отображались только платежи с поставщиками, клиентами и т. д., вы можете сделать:
$payments : Payment::whereHas('vendors')->whereHas('clients')->get();
Выше вы получите только платежи, которые содержат хотя бы одного поставщика и 1 клиента.
Кроме того, вы используете load(), что означает ленивую загрузку. Он разработан таким образом, что вы можете сначала получить основную коллекцию, а затем, когда и если вам нужно, получить только коллекцию отношений.
Отметьте with(), если вы не хотите лениво загружаться.
Кроме того, если вы хотите избежать быстрой загрузки, вы можете выбрать join, но опять же, тогда вы не будете использовать определенные отношения.
На самом деле я использую with() в приведенной выше ситуации.
Я считаю, что вам действительно нужно использовать with()рядомwhereHas(), чтобы и с нетерпением загружал только модели с такими отношениями.
Это не похоже на ошибку, но, безусловно, это то, что можно оптимизировать. Я бы предложил сделать пул реквест или проблему на репозиторий фреймворка Laravel.