Eloquent mặc định lazy load: truy cập $post->author mà chưa eager load thì mỗi post sinh thêm một query. Với 100 post là 101 query, và trên local dữ liệu ít nên không ai nhận ra.
Chặn ngay từ dev bằng preventLazyLoading trong AppServiceProvider::boot():
use Illuminate\Database\Eloquent\Model;
public function boot(): void
{
Model::preventLazyLoading(! app()->isProduction());
}Mọi lần lazy load sẽ ném LazyLoadingViolationException kèm tên model và tên relation — lỗi hiện ngay khi chạy test hoặc mở trang, thay vì thành query chậm sau này.
Trên production thường không nên ném exception cho người dùng; chuyển sang ghi log:
Model::handleLazyLoadingViolationUsing(function (Model $model, string $relation) {
Log::warning('lazy loading violation', ['model' => $model::class, 'relation' => $relation]);
});Cách sửa khi bị bắt lỗi:
- with(['author', 'comments.user']) để eager load theo nhu cầu; load() khi model đã nạp rồi.
- Chỉ cần đếm thì withCount('comments') thay vì nạp cả collection.
- Chỉ cần vài cột thì with(['author:id,name']).
- Quan hệ dùng ở hầu hết mọi chỗ mới đặt vào $with của model; đặt bừa sẽ nạp thừa.
Bộ đôi còn lại cùng họ: preventSilentlyDiscardingAttributes() (bắt lỗi fill field không nằm trong $fillable) và preventAccessingMissingAttributes() (bắt đọc cột không được select). Cả ba gộp trong Model::shouldBeStrict().