Add lazy-load guard to detect N+1 relation queries - #591
KalimeroMK wants to merge 7 commits into
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #591 +/- ##
=========================================
Coverage 99.69% 99.69%
- Complexity 662 668 +6
=========================================
Files 43 45 +2
Lines 1622 1648 +26
=========================================
+ Hits 1617 1643 +26
Misses 5 5 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Tigrov
left a comment
There was a problem hiding this comment.
Two questions:
- Is this only for development or debugging / profiling?
- Why is
LazyLoadGuardnot designed as a class attribute#[Attribute(Attribute::TARGET_CLASS)]? It will not require properties$onlyand$exceptif apply the attribute to a specified AR class.
You're right that If you'd prefer, I can reduce this PR to just the |
Tigrov
left a comment
There was a problem hiding this comment.
The solution looks a bit complicated. Perhaps better to move it to a separate trait where the counter will be enabled inside the method retrieveRelation() without using events. Then it will allow to use only this trait without difficult configurations.
|
Thanks, agreed, the event-based setup was too heavy. Reworked it:
LazyLoadGuard::set(LazyLoadGuardMode::Strict);
// or
LazyLoadGuard::set(LazyLoadGuardMode::Log, $logger);
Docs moved to |
Closes #590
What —
LazyLoadGuardTraitoverridesretrieveRelation()and reports every lazy load toLazyLoadGuard, which hasLog(default) /Strictmodes and is configured statically:LazyLoadGuard::set(LazyLoadGuardMode::Strict)orLazyLoadGuard::set(LazyLoadGuardMode::Log, $logger). No events and no dispatcher configuration; models without the trait are not affected. Meant for development and testing.How —
retrieveRelation()is the single lazy-load path;with()populates$relatedup front sorelation()returns before reaching it. Works together withEventsTrait, which doesn't overrideretrieveRelation().psr/logadded to require-dev + suggest and registered incomposer-dependency-analyser.phpalongside the other opt-in packages.Tests —
tests/LazyLoadGuardTest.php, 9 cases across all five drivers: counting lazy loads, not counting afterwith(), each mode, combination withEventsTrait, andreset().Sqlite suite green (467 tests, 2022 assertions). Psalm, Rector, PHP CS Fixer and composer-dependency-analyser clean.