mpyw/compoships-eager-limit
Install the Package:
composer require mpyw/compoships-eager-limit
Ensure topclaudy/compoships (^2.0.4) and staudenmeir/eloquent-eager-limit (^1.7.1) are also installed (handled automatically via dependencies).
Publish Config (if needed):
The package extends compoships and eloquent-eager-limit without requiring additional configuration. No config file is published by default.
First Use Case:
Replace eager-loading with with() in your Compoships relationships to limit nested eager-loaded results:
// Before (unlimited eager-load)
$posts = Post::with('comments.user')->get();
// After (limited eager-load)
$posts = Post::with(['comments' => function ($query) {
$query->limit(5)->with(['user' => function ($query) {
$query->limit(3); // Nested limit
}]);
}])->get();
Compoships + Eager-Limit Integration:
Use with() clauses on Compoships relationships to apply limits to nested eager-loaded models. The package bridges compoships' polymorphic/morph-many relationships with eloquent-eager-limit's query constraints.
Nested Relationships:
Chain with() calls to limit results at any depth:
$user = User::with([
'posts' => function ($query) {
$query->limit(10)->where('published', true);
},
'roles' => function ($query) {
$query->limit(3)->orderBy('name');
}
])->find(1);
Dynamic Limits: Pass limits dynamically via closures or helper methods:
$limit = request()->input('comments_limit', 5);
$posts = Post::with(['comments' => fn($q) => $q->limit($limit)])->get();
Performance Optimization:
with() for relationships you intend to access.select() to reduce payload:
$posts = Post::with(['comments.user' => fn($q) => $q->limit(2)])
->select('id', 'title')
->get();
Compoships-Specific Patterns:
$item = Item::with(['comments' => fn($q) => $q->limit(5)])->find(1);
$user = User::with(['morphComments' => fn($q) => $q->limit(3)])->find(1);
Query Scoping: Extend the package’s behavior by creating custom scopes:
// app/Models/Post.php
public function scopeWithLimitedComments($query, $limit = 5) {
return $query->with(['comments' => fn($q) => $q->limit($limit)]);
}
Usage:
$posts = Post::withLimitedComments(10)->get();
Laravel 11+ Compatibility:
compoships not yet supporting Laravel 11’s built-in eloquent-eager-limit. Monitor PR #180 for deprecation.compoships + core eloquent-eager-limit.Over-Limiting:
limit(0) or negative values may break queries. Validate inputs:
$limit = max(1, (int) request('limit', 10));
Caching Quirks:
remember() or replicate(), ensure limits are reapplied:
$posts = Post::with(['comments' => fn($q) => $q->limit(5)])->remember(60)->get();
Ordering Conflicts:
orderBy(). Ensure consistent ordering when combining:
// Avoid: Unpredictable results if `created_at` is not indexed.
$query->limit(5)->orderBy('created_at');
Compoships-Specific Issues:
// app/Models/Comment.php
protected $morphClass = 'Commentable';
whereMorphTo or whereMorphLike queries may not play well with limits. Test thoroughly.Query Logging: Enable Laravel’s query logging to verify limits are applied:
\DB::enableQueryLog();
$posts = Post::with(['comments' => fn($q) => $q->limit(3)])->get();
dd(\DB::getQueryLog());
Isolation Testing: Test limits in isolation to rule out other query builders:
// Test the limit alone
$comments = Comment::where('post_id', 1)->limit(3)->get();
Package Overrides:
If the package doesn’t work as expected, check for method overrides in compoships or eloquent-eager-limit:
composer show -a | grep "compoships\|eloquent-eager-limit"
Custom Limit Macros: Add reusable limit logic via macros:
// app/Providers/AppServiceProvider.php
use Illuminate\Database\Eloquent\Builder;
public function boot() {
Builder::macro('withPaginated', function ($relation, $perPage = 10) {
return $this->with([$relation => fn($q) => $q->limit($perPage)]);
});
}
Usage:
$posts = Post::withPaginated('comments', 5)->get();
Event Listeners:
Hook into eloquent.eager.loaded to post-process limited results:
// app/Providers/EventServiceProvider.php
protected $listen = [
'eloquent.eager.loaded' => [\App\Listeners\LogLimitedResults::class],
];
Service Provider Binding: Bind custom limit strategies:
// app/Providers/AppServiceProvider.php
public function register() {
$this->app->bind(\Mpyw\ComposhipsEagerLimit\LimitStrategy::class, function () {
return new \App\Services\CustomLimitStrategy();
});
}
Testing: Use the package’s test suite as a reference for edge cases:
composer test
Focus on:
where, orderBy).`How can I help you explore Laravel packages today?