Weave 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 Nestable Laravel Package

atayahmet/laravel-nestable

Laravel Nestable provides a simple trait for managing hierarchical Eloquent models. Build nested menus, categories, and trees with easy reordering, moving nodes, and querying parents, children, and descendants.

View on GitHub
Deep Wiki
Context7

Getting Started

Install via Composer (composer require atayahmet/laravel-nestable) and register the service provider if you are on Laravel 5.x (package predates auto-discovery). Add the migration columns the package expects — this is a Nested Set implementation, so your table needs _lft, _rgt, parent_id, and (typically) depth/level. The readme shows the exact helper; if you are hand-writing the migration, mirror those column names or the trait's queries will silently misbehave.

Add the provided trait (e.g. NestableTrait) to your Category model. That is the whole integration surface — the trait exposes scopes and instance methods for tree queries and node moves.

First use case that pays for itself immediately: a category/menu table where the read is a full tree or a subtree, rendered recursively. Seed a handful of rows by using the package's "append child" helpers rather than inserting raw rows, since _lft/_rgt values must be maintained as a contiguous sequence. Then call the tree/subtree scope and pass the collection into a recursive Blade partial. That covers navigation menus, breadcrumbs, and category browse pages — the three places developers reach for a nested set model.

Implementation Patterns

  • Model-as-tree, not adjacency list. Do not query where parent_id = ? in a loop. Fetch the whole subtree (or full tree) in one query via the nested-set scope and shape it in PHP. This is the entire value proposition — one indexed query (_llft between ? and ?) replaces N recursive queries.
  • Admin drag-and-drop. Every UI move (reparent, reorder sibling) maps to a package call that rewrites _lft/_rgt. Wrap the move and adjacent logging in a DB transaction; nested set updates touch many rows.
  • Rendering. Materialize the tree once per request and pass a keyed array ([$parentId => [$children]]) to a recursive Blade partial. Avoid lazy-loading children relations in views — you will recreate the N+1 the package exists to avoid.
  • Caching. Because reads are cheap but writes invalidate the whole tree, cache the serialized tree (or subtree) under a versioned key and bump the version on any write. This is a natural fit for menu/nav trees that change rarely.
  • Multiple trees in one table. If you need per-tenant or per-site categories, add a scope_id (or similar) column and always constrain the tree queries by it. Note the package's default scopes may not know about your custom column — verify before relying on it.
  • API shape. Return nested JSON by walking the in-memory tree once; do not return flat rows with parent_id and make the client reconstruct it.

Gotchas and Tips

  • Archived project. Last release 2016, no Laravel 6+ / PHP 7.3+ guarantees. Pin the version, and if you are on a modern stack, test the trait's Eloquent assumptions (getKeyName, mass assignment, withoutGlobalScopes) early. If it breaks, a fork is usually cheaper than migrating to kalnoy/nestedset, which is the actively maintained successor and worth considering up front.
  • Nested set writes are expensive. Every insert or move rewrites up to half the rows. Batch imports inside a transaction and disable the package's per-row maintenance during bulk seeding if it exposes that; otherwise seeding thousands of nodes will crawl.
  • Corruption is silent. _lft/_rgt must be a contiguous, non-overlapping sequence. A crash mid-move, a manual SQL edit, or a bulk insert bypassing the trait leaves an inconsistent tree that mostly works. Always run the package's rebuild/repair routine after data migrations, and add a sanity check (max _rgt vs row count, no overlaps) to your test suite.
  • Deleting a parent. Decide explicitly whether children are promoted, deleted recursively, or left orphaned. Verify what the trait does by default rather than assuming — orphaned rows with dangling parent_id and now-invalid lft/rgt ranges are a common post-mortem.
  • Column name collisions. _lft, _rgt, depth are conventional but check your other packages (e.g. auditing, tagging) before naming.
  • Debugging: when a tree renders wrong, dump id, parent_id, _lft, _rgt, depth sorted by _lft. Gaps, overlaps, or _rgt <= _lft immediately point to the broken node — don't debug through the Blade layer.
  • Extension points: the trait is meant to be overridden — subclass methods for custom ordering, soft-delete behavior, or scoping. Prefer local scopes in your own model over patching the vendor trait; it keeps future framework upgrades survivable.
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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums