Fluent API
Ancestry provides a fluent, chainable API for managing hierarchies. This guide covers both conductor types.
For Model Conductor
Section titled “For Model Conductor”The for() conductor starts operations on a specific model:
use Cline\Ancestry\Facades\Ancestry;
Ancestry::for($model)->type('seller')->...Setting the Type
Section titled “Setting the Type”Always set the hierarchy type before performing operations:
$conductor = Ancestry::for($seller)->type('seller');Adding to Ancestor
Section titled “Adding to Ancestor”// Add as rootAncestry::for($seller)->type('seller')->add();
// Add with parentAncestry::for($seller)->type('seller')->add($manager);Attaching and Detaching
Section titled “Attaching and Detaching”// Attach to parentAncestry::for($seller)->type('seller')->attachTo($manager);
// Detach from parent (become root)Ancestry::for($seller)->type('seller')->detach();Moving
Section titled “Moving”// Move to new parentAncestry::for($seller)->type('seller')->moveTo($newManager);
// Move to become rootAncestry::for($seller)->type('seller')->moveTo(null);Removing
Section titled “Removing”Ancestry::for($seller)->type('seller')->remove();Querying Relationships
Section titled “Querying Relationships”// Get ancestors$ancestors = Ancestry::for($seller)->type('seller')->ancestors();$ancestorsWithSelf = Ancestry::for($seller)->type('seller')->ancestors(includeSelf: true);$nearestTwo = Ancestry::for($seller)->type('seller')->ancestors(maxDepth: 2);
// Get descendants$descendants = Ancestry::for($ceo)->type('seller')->descendants();$children = Ancestry::for($ceo)->type('seller')->descendants(maxDepth: 1);
// Get parent$parent = Ancestry::for($seller)->type('seller')->parent();
// Get children$children = Ancestry::for($manager)->type('seller')->children();
// Get siblings$siblings = Ancestry::for($seller)->type('seller')->siblings();$siblingsWithSelf = Ancestry::for($seller)->type('seller')->siblings(includeSelf: true);Checking Relationships
Section titled “Checking Relationships”// Check ancestry$isAncestor = Ancestry::for($ceo)->type('seller')->isAncestorOf($seller);$isDescendant = Ancestry::for($seller)->type('seller')->isDescendantOf($ceo);
// Check position$isInAncestry = Ancestry::for($seller)->type('seller')->isInAncestry();$isRoot = Ancestry::for($ceo)->type('seller')->isRoot();$isLeaf = Ancestry::for($seller)->type('seller')->isLeaf();Getting Position Information
Section titled “Getting Position Information”// Get depth$depth = Ancestry::for($seller)->type('seller')->depth();
// Get roots$roots = Ancestry::for($seller)->type('seller')->roots();
// Get path from root$path = Ancestry::for($seller)->type('seller')->path();
// Build tree$tree = Ancestry::for($ceo)->type('seller')->tree();Chaining Operations
Section titled “Chaining Operations”The conductor returns itself for modification operations, allowing chaining:
Ancestry::for($seller) ->type('seller') ->add($manager) ->detach() ->attachTo($newManager);Type Conductor
Section titled “Type Conductor”The ofType() conductor starts operations on a hierarchy type:
use Cline\Ancestry\Facades\Ancestry;
Ancestry::ofType('seller')->...Getting Root Nodes
Section titled “Getting Root Nodes”$roots = Ancestry::ofType('seller')->roots();Adding Models
Section titled “Adding Models”// Add as rootAncestry::ofType('seller')->add($seller);
// Add with parentAncestry::ofType('seller')->add($seller, $manager);Getting Model Conductor
Section titled “Getting Model Conductor”You can transition to a model conductor with the type already set:
$conductor = Ancestry::ofType('seller')->for($seller);
// Now perform operations without setting type again$ancestors = $conductor->ancestors();$conductor->moveTo($newManager);Combining Approaches
Section titled “Combining Approaches”You can use both conductors together for expressive code:
// Get all roots in the seller hierarchy$roots = Ancestry::ofType('seller')->roots();
// For each root, get all descendantsforeach ($roots as $root) { $descendants = Ancestry::for($root) ->type('seller') ->descendants();
// Or using ofType $descendants = Ancestry::ofType('seller') ->for($root) ->descendants();}Error Handling
Section titled “Error Handling”The conductor throws a RuntimeException if you try to perform operations without setting the type:
// This will throw an exceptionAncestry::for($seller)->ancestors(); // RuntimeException: Ancestor type must be setAlways set the type first:
Ancestry::for($seller)->type('seller')->ancestors(); // Works!