Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Eloquent Eager Limit Laravel Package

staudenmeir/eloquent-eager-limit

Add per-parent limits to eager-loaded Eloquent relationships in Laravel. Load only the latest N related models for each parent (e.g., newest comments per post) without N+1 queries. Supports common relations and integrates cleanly with queries and pagination.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require staudenmeir/eloquent-eager-limit
    

    No additional configuration is required—it integrates automatically with Eloquent.

  2. First Use Case: Limited Eager Loading Fetch only the 3 most recent comments per blog post:

    $posts = Post::with(['comments' => function ($query) {
        $query->orderBy('created_at', 'desc')->limit(3);
    }])->get();
    

    Replace with the package’s syntax:

    $posts = Post::withLimit(['comments' => 3], 'created_at', 'desc')->get();
    
  3. Where to Look First

    • GitHub Repository (for advanced usage).
    • Laravel’s Eloquent documentation for relationship syntax (e.g., hasMany, belongsToMany).
    • Package’s tests for edge cases.

Implementation Patterns

Core Workflows

  1. Basic Limited Eager Loading

    // Fetch 2 latest replies per thread
    $threads = Thread::withLimit(['replies' => 2], 'created_at', 'desc')->get();
    
  2. Nested Relationships

    // Fetch 1 top comment + 1 top reply per comment (max 2 replies)
    $posts = Post::withLimit([
        'comments' => 1,
        'comments.replies' => 2
    ], 'created_at', 'desc')->get();
    
  3. Dynamic Limits via Closures

    $posts = Post::withLimit(function ($query) {
        return $query->limit(5)->where('published', true);
    })->get();
    
  4. Combining with Other Query Methods

    // Paginate posts with limited comments
    $posts = Post::withLimit(['comments' => 3])
        ->paginate(10)
        ->appends(['comments_limit' => 3]);
    
  5. Offset Support (for Pagination)

    // Skip 2 oldest comments, fetch next 3
    $posts = Post::withLimit(['comments' => [3, 2]], 'created_at', 'asc')->get();
    

Integration Tips

  • API Responses: Use withLimit to control payload size for endpoints like /posts/{id}/comments.
  • Admin Panels: Limit nested relations (e.g., users.orders.items) to avoid overwhelming dashboards.
  • Caching: Cache limited eager-loaded results with remember():
    $posts = Post::withLimit(['comments' => 5])
        ->remember(60)
        ->get();
    

Gotchas and Tips

Pitfalls

  1. Database-Specific Quirks

    • SQL Server: May require TOP syntax adjustments (package handles this automatically).
    • MySQL 5.7+: Works natively, but older versions might need LIMIT in subqueries.
    • SQLite: Test with large datasets—some edge cases may arise with nested LIMIT in subqueries.
  2. Ordering Without a Column

    • Error: withLimit(['comments' => 3]) without an order column throws an exception.
    • Fix: Always specify orderBy:
      withLimit(['comments' => 3], 'created_at', 'desc')
      
  3. Nested Limits and Performance

    • Issue: Deeply nested withLimit (e.g., A.B.C.D) can bloat queries.
    • Tip: Flatten relationships or use separate queries for complex cases.
  4. Offset Misuse

    • Gotcha: [limit, offset] syntax is per parent, not global. For global offsets, use raw queries or cursor().
  5. Polymorphic Relations

    • Workaround: Cast to the correct model before limiting:
      $posts = Post::withLimit(['comments' => 2])->get();
      foreach ($posts as $post) {
          $post->comments = $post->comments->sortBy('created_at');
      }
      

Debugging

  • Query Logging: Enable Laravel’s query logging to verify generated SQL:
    \DB::enableQueryLog();
    $posts = Post::withLimit(['comments' => 3])->get();
    dd(\DB::getQueryLog());
    
  • Common Errors:
    • Column not found: Ensure the orderBy column exists in the related table.
    • Syntax error: Check for unsupported database syntax (e.g., SQLite’s LIMIT in subqueries).

Extension Points

  1. Custom Drivers Override the LimitClause logic in staudenmeir/eloquent-eager-limit/src/LimitClause.php for unsupported databases.

  2. Dynamic Limits via Observers/Events

    Post::observe(function ($post) {
        if (auth()->check()) {
            $post->loadWithLimit(['comments' => 10]);
        }
    });
    
  3. Macros for Reusability

    use Staudenmeir\EloquentEagerLimit\LimitClause;
    
    EloquentBuilder::macro('withLatestComments', function ($limit = 5) {
        return $this->withLimit(['comments' => $limit], 'created_at', 'desc');
    });
    

    Usage:

    $posts = Post::withLatestComments()->get();
    
  4. Testing Mock the LimitClause in PHPUnit:

    $this->partialMock(LimitClause::class, function ($mock) {
        $mock->shouldReceive('getQuery')->andReturn($query);
    });
    

```markdown
### Configuration Quirks
- **No Config File**: The package auto-detects database drivers; no `config/eloquent-eager-limit.php` exists.
- **Global Defaults**: Not supported—set limits per query or via macros.
- **Pivot Tables**: Works with `belongsToMany`, but ensure the pivot has an orderable column (e.g., `created_at`).
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle