Eloquent за замовчуванням поблажливий: багато помилок не падають, а мовчки дають неправильний результат. Model::shouldBeStrict() вмикає три перевірки одночасно:
// AppServiceProvider::boot()
Model::shouldBeStrict(! $this->app->isProduction());
1. preventLazyLoading - заборона лінивого завантаження зв'язків:
$posts = Post::all();
foreach ($posts as $post) {
$post->author->name; // LazyLoadingViolationException
}
Ловить N+1 у момент написання коду, а не після скарг на повільну сторінку. Виправлення - Post::with('author').
2. preventSilentlyDiscardingAttributes - помилка при масовому заповненні полями, яких немає в $fillable:
User::create(['name' => 'Olena', 'is_admin' => true]); // MassAssignmentException
Без суворого режиму is_admin мовчки відкидається. Звучить безпечно, але це й джерело багів: додали поле у форму, забули в $fillable - дані не зберігаються, і ніхто не розуміє чому.
3. preventAccessingMissingAttributes - помилка при зверненні до атрибута, якого немає в моделі:
$user = User::select('id', 'name')->first();
$user->email; // MissingAttributeException замість тихого null
Ловить запити з неповним select() і опечатки в назвах атрибутів.
Чому не на продакшені: виняток у лінивому завантаженні ламає сторінку для користувача там, де раніше вона просто працювала повільніше. Тому типова схема - суворо в розробці й тестах, м'яко на продакшені з логуванням:
Model::preventLazyLoading();
Model::handleLazyLoadingViolationUsing(function (Model $model, string $relation): void {
if (app()->isProduction()) {
Log::warning('Lazy loading', ['model' => $model::class, 'relation' => $relation]);
return;
}
throw new LazyLoadingViolationException($model, $relation);
});
Нюанси:
- одна модель - лінивий виклик зв'язку для моделі, отриманої не в колекції, не вважається порушенням (N+1 там неможливий);
Model::automaticallyEagerLoadRelationships()- альтернативний підхід: Eloquent сам довантажує зв'язок для всієї колекції при першому зверненні;- увімкнення на старому проєкті покаже десятки порушень - вмикайте поступово й лагодьте, інакше команда просто вимкне перевірку;
- тести - найкраще місце для суворого режиму: порушення в тестах ламають CI ще до рев'ю.