1. Problem N+1 przy Lazy Loading
Domyślnie Eloquent korzysta z lazy loading. Dane relacyjne są ładowane dopiero przy dostępie.
Często prowadzi to do problemu N+1 zapytań.
$users = User::all(); // 1 zapytanie
foreach ($users as $user) {
$user->posts; // +1 zapytanie na użytkownika ❌
}
100 użytkowników = 101 zapytań 😱
2. Eager Loading – dobre rozwiązanie
Rozwiązaniem jest eager loading:
$users = User::with('posts')->get(); // łącznie tylko 2 zapytania ✅
Można ładować relacje zagnieżdżone:
$users = User::with('posts.comments')->get();
3. Warunkowe ładowanie relacji
Nie zawsze trzeba ładować wszystkie dane.
- Filtrowanie relacji
$users = User::with(['posts' => fn($q) => $q->where('is_active', true)])->get();
- Ładowanie tylko gdy brakuje
$user->loadMissing('posts');
- Połączenie z filtracją (
withWhereHas)
$users = User::withWhereHas('posts', fn($q) => $q->where('is_active', true))->get();
4. Model::shouldBeStrict() – strażnik w developmentcie
Włącz strict mode w AppServiceProvider:
use Illuminate\Database\Eloquent\Model;
public function boot(): void
{
Model::shouldBeStrict();
}
Korzyści:
- Laravel rzuci wyjątek przy lazy loadingu w pętli
- Wykryje nieistniejące atrybuty
- Bezpieczniejszy workflow w dev
Na produkcji można użyć:
Model::preventLazyLoading(! app()->isProduction());
Dzięki temu w dev są wyjątki, a w produkcji tylko warningi.
5. Checklista dobrych praktyk ✅
- Używaj
with()gdy wiesz, że potrzebujesz relacji - Do agregacji stosuj
withCount()zamiast ładować całą relację - Do warunkowego ładowania używaj
withWhereHas - Włącz
Model::shouldBeStrict()w dev - Monitoruj zapytania (Laravel Debugbar, Telescope, Clockwork)