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

Laravel Nestedset Laravel Package

vusys/laravel-nestedset

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require vusys/laravel-nestedset
    

    Publish the migration (if using the built-in schema):

    php artisan vendor:publish --provider="Vusys\NestedSet\NestedSetServiceProvider" --tag="migrations"
    php artisan migrate
    
  2. Model Integration: Use the HasNestedSet trait in your Eloquent model:

    use Vusys\NestedSet\HasNestedSet;
    
    class Category extends Model
    {
        use HasNestedSet;
    
        protected $fillable = ['name', 'lft', 'rgt', 'depth'];
    }
    
  3. First Use Case: Create a root node:

    $root = Category::create(['name' => 'Root']);
    $root->save(); // Automatically sets lft/rgt/depth
    

    Insert a child:

    $child = $root->appendChild(['name' => 'Child']);
    $child->save();
    

Key Files to Review


Implementation Patterns

Common Workflows

  1. Hierarchy Management:

    • Append/Insert:
      // Append as last child
      $parent->appendChild(['name' => 'New Child']);
      
      // Insert at specific position (e.g., 2nd child)
      $parent->insertChild(2, ['name' => 'Middle Child']);
      
    • Move Nodes:
      $node->moveTo($newParent, 'last-child'); // or 'first-child', 'before', 'after'
      
  2. Querying:

    • Scope Children:
      $children = Category::whereParentId($parentId)->get();
      
    • Depth-Based Queries:
      $shallowNodes = Category::whereDepth('<', 3)->get();
      
    • Path Queries:
      $path = $node->getPath(); // Array of ancestors
      
  3. Bulk Operations:

    • Reorder Subtree:
      $subtree = Category::whereIn('id', [$id1, $id2])->reorder();
      
  4. Event Hooks:

    • Listen for nestedset.saving, nestedset.saved, etc.:
      Category::saved(function ($model) {
          // Post-save logic (e.g., cache updates)
      });
      

Integration Tips

  • Custom Columns: Override getLeftAttribute(), getRightAttribute(), etc., if using non-standard column names.
  • Soft Deletes: Extend the trait to handle deleted_at:
     use Illuminate\Database\Eloquent\SoftDeletes;
    
     class Category extends Model
     {
         use HasNestedSet, SoftDeletes;
     }
    
  • API Responses: Use accessors to flatten hierarchy in JSON:
     public function getChildrenAttribute()
     {
         return $this->children()->get();
     }
    

Gotchas and Tips

Pitfalls

  1. Database Locks:

    • Large-scale reordering (reorder()) may cause locks. Use transactions:
      DB::transaction(function () {
          $node->moveTo($parent, 'last-child');
      });
      
  2. Circular References:

    • Avoid recursive loops when moving nodes. Validate parent-child relationships:
      if ($node->isDescendantOf($newParent)) {
          throw new \Exception("Cannot move node under itself.");
      }
      
  3. Performance:

    • Avoid getDescendants() on deep trees in loops. Use cursors or pagination:
      $descendants = $node->descendants()->cursor();
      
  4. Migration Conflicts:

    • If extending an existing table, manually add lft, rgt, depth columns with unsignedBigInteger type.

Debugging

  • Validate lft/rgt: Check for gaps or overlaps with:

    SELECT lft, rgt, id FROM categories ORDER BY lft;
    

    Use php artisan nestedset:repair if corrupted.

  • Log Events: Enable debug logging for nested-set events in config/nestedset.php:

    'debug' => env('NESTEDSET_DEBUG', false),
    

Extension Points

  1. Custom Storage: Override getLeftAttribute() to use a different column:

    protected function getLeftAttribute($value)
    {
        return $this->{$this->getLeftColumn()} ?? $value;
    }
    
  2. Hooks: Extend the trait to add pre/post-save logic:

    protected static function bootHasNestedSet()
    {
        static::saved(function ($model) {
            // Custom logic
        });
    }
    
  3. Query Scopes: Add custom scopes to HasNestedSet:

    public function scopeActive($query)
    {
        return $query->where('active', true);
    }
    

Configuration Quirks

  • Default Order: The package assumes lft/rgt are unsignedBigInteger. Change in config/nestedset.php if needed:

    'columns' => [
        'left' => 'lft',
        'right' => 'rgt',
        'depth' => 'depth',
    ],
    
  • Tree Depth Limit: Default depth column is tinyInteger. Increase to smallInteger for >127 levels:

    Schema::table('categories', function (Blueprint $table) {
        $table->smallInteger('depth')->unsigned()->default(0);
    });
    
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.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle