While working on the upcoming https://ohdear.app redesign, I noticed that list that displays all sites of a team was very slow. Let's look at a simplified version of how we fetch the data to build the site list for the current team.
When displaying a site list for teams with 200 sites, 200 extra queries are performed, and this is what makes the site list slow.
Here's the modified code: $sites = Team::current() // returns an instance of the team model ->sites() ->with('team') ->get() ->filter(fn (Site $site) => currentUser()->can('administer', $site)); This successfully solves the N+1 problem.
$team = Team::current(); $team ->sites() ->get() ->map(fn (Site $site) => $site->setRelation('team', $team)) ->filter(fn (Site $site) => currentUser()->can('administer', $site)); By using setRelation, Eloquent will not reach out to the database anymore to get the team relation, it will simply return the Team instance we passed.
Achieve superior email deliverability with ToastMail! Our AI-driven tool warms up inboxes, monitors reputation, and ensures emails reach their intended destination. Sign up today for a spam-free future.