aki77/strict_lazy/strict-lazy
Claude Code and agent skill by aki77/strict_lazy
- community
Checking that the SKILL.md file is still in the repository.
How to use the strict_lazy gem to eliminate N+1 for 'computed values' (external APIs, window functions, cross-table aggregations) that cannot be expressed with preload/includes — by requiring explicit preloads and raising on unpreloaded reads in dev/test. Use when: (1) fixing N+1 in a list where the cause is aggregation/external API/computed methods rather than associations, (2) implementing pre-loading for such values. Out of scope: N+1 expressible via associations (use includes/preload/strict_loading instead).
Install
npx vskill@latest install aki77/strict_lazy/strict-lazySKILL.md
strict_lazy
A gem that brings strict_loading to computed values. Forces controllers to explicitly preload values that cannot be expressed as associations, and raises on unpreloaded reads in dev/test. Only depends on activesupport.
First: determine applicability
If the value can be expressed via belongs_to/has_many, use the standard solution instead of strict_lazy. Misuse adds unnecessary complexity.
| N+1 cause | Tool | |
|---|---|---|
| Traversing associations | includes / preload / eager_load | |
| Detecting unloaded associations | strict_loading / bullet | |
| Computed values not expressible as associations | strict_lazy |
strict_lazy is only for values that can't be written with preload:
- External APIs: things that can be fetched in bulk like
Svc.bulk_fetch(ids) - Window functions / raw SQL: e.g.
ROW_NUMBER() OVER (...) - Cross-table aggregations: e.g.
group(:post_id).count(prefercounter_cachewhen it suffices)
Usage (4 required pieces — missing any one breaks it)
1. Declare in the model
The resolver is either a block or `from:` (class method name) — mutually exclusive. Both receive (records, loader) and call loader.call(record, value) for each resolved record. Runs exactly once for the whole group, so consolidate into 1 query/1 API call here.
Records not called with loader.call receive the default: value (how Posts with 0 comments get default: 0 when absent from GROUP BY results).
2. Preload in the controller
Match the collection you read in the view. sync: false (default) resolves lazily on first .lazy read and memoizes; sync: true resolves immediately at preload time.
3. Read via .lazy. in the view
No plain method is defined. Always go through .lazy..
4. Forgotten preloads raise
violation on unpreloaded reads: :raise (default dev/test — no wasted queries) / :log (warn then resolve 1 record) / :ignore (default prod — silently resolves 1 record = N+1). Override with StrictLazy.violation= or config.strict_lazy.violation.
Pitfalls
- Forgetting
.lazy.→ reads a normal method/column, preload has no effect - Defining
from:afterlazy_load→ raises at declaration time (no restriction for blocks) - Writing the resolver one record at a time → N+1 persists. Use
recordsto consolidate into one call default: []and other mutable shared objects → use callable:-> { [] }(arity 0) /->(r) { ... }(arity 1). Static values are fine as-is- Preload group and view collection don't match → unpreloaded records raise
For full argument details and behavior, see references/api.md.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/strict-lazy/SKILL.md
Popularity
- Repository stars
- 1
- 7-day trend score
- 0
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/aki77/strict_lazy/strict-lazy)