Skip to content
Back to skills

Laravel Eloquent Nplus1

ASecurity

Detects N+1 query patterns (relation access inside loops without eager loading), full-table get()/all() loads, and unsafe chunk()/cursor() usage in Laravel Eloquent code.

  • 4 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 2, 2026
ai-agentsgophpsqlperformance

Works with

  • cursor

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned September 2, 2026

npx -y skills add s977043/river-review --skill laravel-eloquent-nplus1 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Laravel Eloquent Nplus1?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Laravel Eloquent Nplus1
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/s977043-laravel-eloquent-nplus1/badge)](https://www.skillsdirectory.com/skills/s977043-laravel-eloquent-nplus1)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
id: 'laravel-eloquent-nplus1'
name: 'Laravel Eloquent N+1 and Query Efficiency Review'
description: 'Detects N+1 query patterns (relation access inside loops without eager loading), full-table get()/all() loads, and unsafe chunk()/cursor() usage in Laravel Eloquent code.'
version: 0.1.0
category: midstream
phase: midstream
applyTo:
  - 'app/**/*.php'
  - 'src/**/*.php'
tags: [laravel, eloquent, performance, n-plus-1, php, midstream]
severity: major
inputContext: [diff]
outputKind: [findings, questions]
modelHint: balanced
---

## Pattern declaration

Primary pattern: Reviewer
Secondary patterns: Inversion
Why: Eloquent のクエリ効率規約への適合をチェックリスト型で検査する

## Goal / 目的

- ループ内 relation アクセスによる N+1 クエリ(公式例: 25 件で 26 クエリ)を検出する。
- 巨大テーブルの全件ロード(`all()` / `get()`)と、`chunk()` / `cursor()` の誤用を検出する。

## Non-goals / 扱わないこと

- mass assignment / 認可(`laravel-mass-assignment` のスコープ)。
- migration の安全性(`laravel-migration-safety` のスコープ)。
- SQL チューニング一般・index 設計。

## Pre-execution Gate / 実行前ゲート

このスキルは以下の条件が**すべて**満たされない限り`NO_REVIEW`を返す。

- [ ] 差分に Eloquent モデルのクエリ・relation アクセスの追加変更が含まれている
- [ ] diff コンテキストが利用可能である

ゲート不成立時の出力: `NO_REVIEW: laravel-eloquent-nplus1 — Eloquent クエリの変更なし`

## False-positive guards / 抑制条件

- ループ前に `with()` / `load()` 済みの relation へのアクセスは指摘しない(diff 外で eager load されている可能性があるため、確証がなければ質問に留める)。
- ループ対象が少数固定(config 由来等)の場合の relation アクセスは指摘しない。
- `chaperone()` を使った親逆参照は正当。
- `preventLazyLoading` が有効なプロジェクトでは N+1 がテストで落ちるため、重複指摘を避ける。

## Rule / ルール

- ループ内で relation を参照する場合は `with('relation')`(取得後なら `load()` / `loadCount()`)で eager load する。
- 巨大テーブルの反復は `chunkById` / `lazyById` / `cursor` を使う。
- `chunk()` でフィルタ対象カラムを更新しない(公式: inconsistent results。`chunkById` を使う)。
- `cursor()` と eager loading を併用しない(cursor は relation を eager load できない。`lazy` を使う)。
- `chunkById` / `lazyById` で `orWhere` を含む条件は closure で論理グループ化する。

## Evidence / 根拠の取り方

- 指摘は `<file>:<line>` で差分に紐づけ、公式規約(laravel.com/docs/12.x/eloquent-relationships#eager-loading 等)を 1 行で添える。
- eager load の有無が diff から確定できない場合は断定せず `questions` で返す。

## Output / 出力(短文版の推奨)

コメントは日本語で返す。

- Finding: N+1 / 全件ロード / chunk 誤用のどれか(1文)
- Impact: クエリ数 / メモリ / 一貫性への影響
- Fix: `with()` / `chunkById` / `lazy` 等の最小修正案

## Sources / 出典

- Laravel 12.x — Eloquent Relationships (Eager Loading): <https://laravel.com/docs/12.x/eloquent-relationships#eager-loading>
- Laravel 12.x — Eloquent (chunk / cursor / strictness): <https://laravel.com/docs/12.x/eloquent>

Files in this skill

  • SKILL.md3.5 KB
  • fixtures/01-nplus1-loop-happy.md866 B
  • fixtures/02-eager-loaded-guard.md873 B
  • golden/01-nplus1-loop-happy.md502 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.