lc-find-n-plus-one
Detect N+1 query problems in Blade views, Livewire components, and controllers.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Detect N+1 query problems in Blade views, Livewire components, and controllers.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Create a Larascraper scraper (v2 or v3) for a target website, chaining browser actions (click, type, wait, scroll), conditional flow (when/repeatUntil), captcha solving, and file/PDF downloads. Detects the installed major and generates the matching style.
Add or edit a Laracrate file collection in config/laracrate.php with the correct anatomy (disk, access, types, variants, previews, extract/embed, flags, per-model scoping).
Runtime-verified Laravel inspection using the Laravel Boost MCP server (Tinker, Database Query/Schema, Last Error) instead of static grep. Falls back to Docker/Tinker if Boost is not installed.
Scaffold spatie/laravel-permission setup - add the HasRoles trait to a model and generate a roles & permissions seeder.
Audit spatie/laravel-permission usage - permissions used in code but undefined, defined but unused, unprotected routes, guard mismatches, and cache pitfalls.
Extract business logic from a controller or Livewire component method into a Laractions Action class.
| name | lc:find-n-plus-one |
| description | Detect N+1 query problems in Blade views, Livewire components, and controllers. |
| argument-hint | [analyze | fix | fix --dry-run | file-path | fix file-path] |
| user-invocable | true |
| allowed-tools | Read Grep Bash Edit Write Glob |
Statically analyze Blade views, Livewire/Volt components, and controllers to detect N+1 query problems where relationships are accessed inside loops without eager loading.
| Subcommand | Description |
|---|---|
| (no argument) | Scan the entire project for N+1 problems. Read-only report. |
fix | Scan and auto-add with() eager loading to queries. Asks for confirmation before each change. |
fix --dry-run | Show what with() calls would be added without changing anything. |
[file-path] | Analyze a specific file and trace its data sources. Read-only. |
fix [file-path] | Fix N+1 issues in a specific file, with confirmation. |
An N+1 query problem occurs when code accesses a relationship on a model inside a loop, causing one query per iteration instead of a single eager-loaded query. For example:
// BAD: N+1 -- runs 1 query for properties + N queries for office
@foreach($properties as $property)
{{ $property->office->name }} // Each iteration hits the database
@endforeach
// GOOD: Eager loaded -- runs 2 queries total
$properties = Property::with('office')->get();
@foreach($properties as $property)
{{ $property->office->name }} // No additional query
@endforeach
[file-path] argument is provided, analyze only that file and trace its data sources.Glob to find:
resources/views/**/*.blade.php (Blade views)app/Http/Controllers/**/*.php (Controllers)app/Livewire/**/*.php (Livewire class components, if any exist)For each Blade file, use Read to load the content and identify:
@foreach, @forelse, @for, @while, and nested loops.$variable->relationship where relationship is a known model relationship$variable->relationship->property$variable->relationship()->...$variable->relationship->count()$variable->loadCount('relationship') inside loops (should be done before the loop)$property->office->organization->name -- multiple levels of lazy loading.To determine if a property access is a relationship:
$appends array (appended attributes are not relationships even if they share a name).For each loop variable, trace where the data comes from:
mount() or computed propertiesrender() or with() methodswith() or load() is called on the queryGrep to find which controller renders this view (return view('view.name', ...))with(), load(), or loadMissing() callsFor each relationship accessed inside a loop, determine:
with('relationship') is called on the query that builds the collection.$with on the model? Some models define protected $with = ['relationship'] for automatic eager loading.loadMissing() or whenLoaded() patterns.Flag as N+1 only if the relationship is NOT eager-loaded by any of these mechanisms.
Beyond simple loop access, check for:
Accessor N+1: Model accessors that access relationships, called from within loops.
// In Model
public function getFullAddressAttribute() {
return $this->location->name . ', ' . $this->location->province->name; // N+1!
}
// In Blade
@foreach($properties as $property)
{{ $property->full_address }} // Triggers N+1 via accessor
@endforeach
Relationship count N+1: Using $model->relationship->count() instead of withCount().
@foreach($properties as $property)
{{ $property->images->count() }} // Loads all images just to count
@endforeach
Conditional relationship access: Relationships accessed inside @if blocks within loops.
@foreach($properties as $property)
@if($property->showcase) // N+1 even though it's conditional
{{ $property->showcase->name }}
@endif
@endforeach
Component rendering N+1: Livewire/Blade components rendered inside loops that internally access relationships.
For each N+1 problem found, report:
N+1 QUERY DETECTED
===================
File: /absolute/path/to/resources/views/livewire/properties/index.blade.php
Line: 45
Loop: @foreach($properties as $property)
Access: $property->office->name
Data Source: Livewire computed property in same file (line 12)
Query: Property::where('organization_id', $this->organizationId)->paginate(20)
Problem: 'office' relationship is not eager-loaded. This will execute 1 additional
query per property in the collection (20 queries for a page of 20).
Fix: Add ->with('office') to the query:
Property::where('organization_id', $this->organizationId)
->with('office')
->paginate(20);
End with a summary table:
N+1 ANALYSIS SUMMARY
======================
Files scanned: 85
Loops analyzed: 142
Relationship accesses: 234
N+1 problems found: 12
By severity:
High (in paginated/large collections): 4
Medium (in moderate collections): 5
Low (in small/bounded collections): 3
Top offenders:
resources/views/livewire/properties/index.blade.php - 4 issues
resources/views/livewire/clients/show.blade.php - 3 issues
resources/views/livewire/operations/table.blade.php - 2 issues
fix or fix [file-path])For each N+1 problem detected, automatically add the missing with() calls:
with() call, or add a new ->with('relationship') clause.->count() access with withCount() on the query.fix --dry-run)Show exactly what query modifications would be made, with before/after diffs, without writing any changes.
->take(5), enum values, etc.).morphTo) are harder to trace -- note these as "needs manual review" if uncertain.$with model property provides automatic eager loading and should be checked before flagging.