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

Nestablecollection Laravel Package

typicms/nestablecollection

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require typicms/nestablecollection
    

    Ensure your project meets the requirements (PHP ^8.3, Laravel 12/13).

  2. Model Setup Add parent_id to $fillable and use the NestableTrait:

    use TypiCMS\NestableTrait;
    
    class Category extends Model
    {
        use NestableTrait;
    
        protected $fillable = ['parent_id', /* ... */];
    }
    
  3. First Use Case Fetch a collection of nested items (e.g., categories, menus, or hierarchical data):

    $categories = Category::all(); // Returns NestableCollection
    $categories->toTree(); // Converts to a nested array
    

Implementation Patterns

Core Workflows

  1. Building Hierarchies Convert flat adjacency-list data to nested structures:

    $tree = Category::all()->toTree();
    // Returns an array like:
    // [
    //     'id' => 1,
    //     'name' => 'Root',
    //     'children' => [...]
    // ]
    
  2. Querying Nested Data Use whereHasNested() to filter nested relationships:

    $categories = Category::whereHasNested('children', function ($query) {
        $query->where('name', 'like', '%Electronics%');
    })->get();
    
  3. Recursive Operations Traverse or modify nested structures:

    $categories->eachRecursive(function ($item) {
        // Process each node (including children)
    });
    
  4. Dynamic Sorting Sort nested collections by custom logic:

    $sorted = Category::all()->sortNested(function ($a, $b) {
        return $a->name <=> $b->name;
    });
    

Integration Tips

  • API Responses Serialize nested data directly:

    return response()->json($categories->toTree());
    
  • Blade Views Render nested structures with @foreach:

    @foreach($categories->toTree() as $category)
        <div>{{ $category['name'] }}</div>
        @include('partials.nested', ['items' => $category['children']])
    @endforeach
    
  • Caching Cache nested collections to avoid repeated queries:

    $tree = Cache::remember('category-tree', now()->addHours(1), function () {
        return Category::all()->toTree();
    });
    

Gotchas and Tips

Pitfalls

  1. Performance with Large Trees

    • toTree() and recursive methods can be memory-intensive for deep hierarchies.
    • Fix: Use limitDepth() to cap recursion:
      $categories->toTree()->limitDepth(3);
      
  2. Circular References

    • If parent_id references itself (e.g., parent_id = id), the collection may loop infinitely.
    • Fix: Validate data before nesting or use ignoreSelfReferences():
      $categories->toTree()->ignoreSelfReferences();
      
  3. Query Scope Conflicts

    • Global scopes (e.g., globalScope) may interfere with nested queries.
    • Fix: Temporarily remove scopes:
      $categories = Category::withoutGlobalScopes(function () {
          return Category::whereHasNested(...)->get();
      });
      

Debugging

  • Inspect Raw Data Use getAdjacencyList() to debug flat structures:

    $flatData = $categories->getAdjacencyList();
    
  • Log Recursive Errors Wrap recursive operations in try-catch:

    try {
        $categories->eachRecursive(...);
    } catch (\Exception $e) {
        Log::error('Nested traversal failed', ['error' => $e->getMessage()]);
    }
    

Extension Points

  1. Custom Tree Formats Override toTree() in your model:

    public function toCustomTree()
    {
        return $this->toTree(function ($item) {
            return [
                'id' => $item['id'],
                'slug' => Str::slug($item['name']),
                'children' => $item['children'] ?? []
            ];
        });
    }
    
  2. Add Nesting Logic Extend the trait for domain-specific rules:

    use TypiCMS\NestableTrait;
    
    class Category extends Model
    {
        use NestableTrait;
    
        public function validateNesting($parent, $child)
        {
            // Custom validation (e.g., prevent siblings with same name)
            return true;
        }
    }
    
  3. Performance Optimizations

    • Lazy Loading: Use cursor() for large datasets:
      $categories = Category::cursor()->toTree();
      
    • Database Indexes: Ensure parent_id is indexed for faster queries.
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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours