Метод laravel методом() по сравнению с методом load()

Я действительно пытался понять разницу между методом with() и load(), но не мог понять.

Как я вижу, использование метода with() "лучше", так как я хочу загрузить отношение. Кажется, что если я использую load(), я загружаю это отношение так же, как если бы я использовал hasMany() (или любой другой метод, который относится к отношению между объектами).

Я ошибаюсь?

Ответы

Ответ 1

Оба выполняют одни и те же конечные результаты - стремятся загрузить связанную модель на первую. Фактически, они оба выполняют точно такие же два запроса. Главное отличие заключается в том, что with() нетерпеливо загружает связанную модель вперед, сразу после первоначального запроса (all(), first() или find(x), например); при использовании load() вы сначала запускаете начальный запрос, а затем загружаете отношение в некоторой более поздней точке.

"Eager" означает, что мы связываем все связанные модели для определенного набора результатов, используя только один запрос, в отличие от необходимости запуска запросов n, где n - количество элементов в исходном наборе.


Загрузка с использованием with()

Если мы хотим загрузить с помощью with(), например:

$users = User::with('comments')->get(); 

... если у нас есть 5 пользователей, следующие два запроса запускаются немедленно:

select * from `users`
select * from `comments` where `comments`.`user_id` in (1, 2, 3, 4, 5)

... и мы получаем набор моделей, которые имеют комментарии к пользовательской модели, поэтому мы можем сделать что-то вроде $users->comments->first()->body.


"ленивая" загрузка с использованием load()

Или мы можем отделить два запроса, сначала получив исходный результат:

$users = User::all();

который запускается:

    select * from `users`

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

$users = $users->load('comments');

который запускает второй запрос:

    select * from `comments` where `comments`.`user_id` in (1, 2, 3, 4, 5)

... и мы получим тот же результат, просто разделим на два шага. Опять же, мы можем вызвать $users->comments->first()->body, чтобы перейти к соответствующей модели для любого элемента.


Зачем использовать load() vs. with()? load() дает вам возможность позже решить, основываясь на каком-либо динамическом состоянии, нужно ли вам выполнить второй запрос. Если, однако, нет вопроса, что вам нужно получить доступ ко всем связанным элементам, используйте with(). (Документы также ссылаются на преимущества кэширования для использования load(), но я не знаком с этим, на самом деле, я считаю, что результаты load() не кэшируемы.)


Альтернативой любому из этих элементов будет цикл через исходный набор результатов и запрос отношения hasMany() для каждого элемента. В этом примере это приведет к выполнению запросов n + 1 или 6. Желаемая загрузка, независимо от того, была ли она выполнена с помощью with() или более поздней версии с load(), выполняется только 2.