РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
687 of 1392 menu

Исключение LazyLoadingViolationException

Исключение LazyLoadingViolationException выбрасывается Eloquent ORM в Laravel, когда происходит попытка ленивой загрузки связанных данных, а функция ленивой загрузки отключена в настройках модели. Это исключение помогает разработчику контролировать количество запросов к базе данных и избегать проблемы N+1.

Причины возникновения

Исключение возникает, когда к модели применяется метод preventLazyLoading. Этот метод может быть вызван глобально в сервис-провайдере или локально в конкретной модели. При доступе к связанной модели через свойство (например, $user->posts) без предварительной жадной загрузки будет выброшено исключение.

Синтаксис

<?php use Illuminate\Database\Eloquent\Model; // Глобальное отключение ленивой загрузки Model::preventLazyLoading(); // Локальное отключение в модели class User extends Model { protected static function booted() { static::preventLazyLoading(); } } ?>

Пример возникновения исключения

Рассмотрим ситуацию, когда ленивая загрузка отключена, а мы пытаемся обратиться к связанной модели без жадной загрузки:

<?php namespace App\Http\Controllers; use App\Models\User; use Illuminate\Database\Eloquent\Model; class UserController extends Controller { public function index() { Model::preventLazyLoading(); $users = User::all(); foreach ($users as $user) { foreach ($user->posts as $post) { echo $post->title; } } } } ?>

Результат выполнения кода:

"LazyLoadingViolationException: Attempted to lazy load [posts] on model [App\Models\User]"

Пример исправления с жадной загрузкой

Чтобы избежать исключения, необходимо использовать жадную загрузку с помощью метода with:

<?php namespace App\Http\Controllers; use App\Models\User; use Illuminate\Database\Eloquent\Model; class UserController extends Controller { public function index() { Model::preventLazyLoading(); $users = User::with('posts')->get(); foreach ($users as $user) { foreach ($user->posts as $post) { echo $post->title; } } } } ?>

Результат выполнения кода:

"Post 1" "Post 2" "Post 3"

Пример локального отключения в модели

Можно отключить ленивую загрузку только для конкретной модели, используя метод booted:

<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class User extends Model { protected static function booted() { static::preventLazyLoading(); } public function posts() { return $this->hasMany(Post::class); } } ?>

Пример проверки режима разработки

Рекомендуется включать защиту только в среде разработки для обнаружения проблем N+1:

<?php namespace App\Providers; use Illuminate\Support\ServiceProvider; use Illuminate\Database\Eloquent\Model; class AppServiceProvider extends ServiceProvider { public function boot() { if ($this->app->environment('local')) { Model::preventLazyLoading(); } } } ?>

Смотрите также

  • исключение ModelNotFoundException,
    которое возникает при отсутствии модели в базе данных
  • исключение MassAssignmentException,
    которое выбрасывается при массовом заполнении неразрешённых полей
  • исключение QueryException,
    которое возникает при ошибках выполнения SQL-запросов
  • исключение RelationNotFoundException,
    которое выбрасывается при попытке загрузить несуществующую связь
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить