Search code examples
laravellaravel-livewire

How to lazy load relations for all collections at once in Laravel


I am developing an application to predict scores of football matches. In the application I update the UI live when the user predicts the scores of match. This is to show the % of people who predicted home team win, draw or away team win. To improve the performance, I cache some of the data queried, but there is one relation that I need to lazy load every time the user changes the prediction.

Here is part of my code.

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
            }
        }
    }
}

From the above code you can see that I am eager loading the matches for the group. Later on in the line after // comment 1 I am loading the predictions for each match. This makes too many calls to database as there are more than 50 matches.

I am wondering if there is a way, where I can lazy load the predictions relation for all the matches at once. This will reduce the query count to just 1.

Is this possible in Laravel?


Solution

  • I have done it like below and it is working now.

    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
                }
            }
        }
    }