Как лениво загружать отношения для всех коллекций сразу в Laravel

#laravel #laravel-livewire

Вопрос:

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

Вот часть моего кода.

 public function getGroupsProperty()
{
    $groups = Cache::remember('groups', '3600', function () {
        return Group::whereId(1)->with('matches')->get();
    });

    foreach($groups as $group) {
        foreach($group->matches as $match) {
            // comment 1
            $predictions = $match->predictions->whereNotNull('team_a_score')->whereNotNull('team_b_score');
            foreach($predictions as $prediction) {
                // code to show prediction chart for the match
            }
        }
    }
}
 

Из приведенного выше кода вы можете видеть, что я с нетерпением жду загрузки matches для group . Позже в строке после // comment 1 того, как я загружу прогнозы на каждый матч. Это вызывает слишком много вызовов в базу данных, так как существует более 50 совпадений.

Мне интересно, есть ли способ, с помощью которого я могу лениво загружать predictions отношения для всех matches сразу. Это уменьшит количество запросов всего до 1.

Возможно ли это в Ларавеле?

Ответ №1:

Вы можете сделать это, если вы прочитаете документацию, вы можете это сделать, и это приведет к загрузке (не ) моделей. with('matches.predictions') Lazy Load

Комментарии:

1. Я думаю, вы меня неправильно поняли. Как я уже упоминал, я кэширую матчи группы. если я кэширую прогнозы с совпадениями, я не получу самые последние прогнозы всех пользователей, когда один пользователь обновит свой прогноз. Поскольку многие пользователи будут предсказывать результаты одновременно, мне нужны детали прогноза в реальном времени, чтобы обновить процентную диаграмму прогноза. Поэтому я хочу лениво загружать прогнозы для всех матчей сразу (а не для отдельных запросов 50 ), когда пользователь предсказывает счет. Функция getGroupsProperty будет вызываться каждый раз, когда пользователь обновляет прогноз.

Ответ №2:

Я сделал это, как показано ниже, и сейчас это работает.

 public function getGroupsProperty()
{
    $groups = Cache::remember('groups', '3600', function () {
        return Group::whereId(1)->with('matches')->get();
    });

    foreach($groups as $group) {
        // lazy load predictions here...
        $group->matches->load('predictions');
        foreach($group->matches as $match) {  
            $predictions = $match->predictions->whereNotNull('team_a_score')->whereNotNull('team_b_score');
            foreach($predictions as $prediction) {
                // code to show prediction chart for the match
            }
        }
    }
}