Acts As Tree

Acts as tree

The information below is copied from the API documentation
http://api.akelos.org/ActiveRecord/Behaviours/AkActsAsTree.html

Makes your model acts as a tree (surprise!). Consider the following example:

class Category extends ActiveRecord {
   var $acts_as = 'tree';
}
 
$Category = new Category;
 
$CategoryA   = $Category->create();
$CategoryAa  = $Category->create();
$CategoryAa1 = $Category->create();
$CategoryAa2 = $Category->create();
$CategoryAb  = $Category->create();
$CategoryB   = $Category->create();
 
$CategoryA->tree->addChild($CategoryAa);
$CategoryA->tree->addChild($CategoryAb);
$CategoryAa->tree->addChild($CategoryAa1);
$CategoryAa->tree->addChild($CategoryAa2);

This will effectively give you:

 Category A
  \_ Category Aa
      \_ Category Aa1
      \_ Category Aa2
  \_ Category Ab
 Category B

OK. Admittedly you won't get a graph in real life. But at least the following functions:

$CategoryA->tree->hasChildren();     # ==> true
$CategoryA->tree->childrenCount();   # ==> 2
$CategoryA->tree->getChildren();     # ==> array($CategoryAa, $CategoryAb)
 
// fairly expensive operation follows
/* (yes, array(parent, array_of_children) is not nice 
but unfortunately PHP doesn't allow for objects as keys) */
$CategoryA->tree->getDescendants();  # ==> array(array($CategoryAa,array($CategoryAa1,$CategoryAa2)),$CategoryAb)
 
$CategoryAa->tree->getChildren();    # ==> array($CategoryAa1, $CategoryAa2)
$CategoryAa->tree->getSiblings();    # ==> array($CategoryAb)
$CategoryAa->tree->hasParent();      # ==> true
$CategoryAa->tree->getParent();      # ==> $CategoryA
 
$CatagoryAa1->tree->hasChildren();   # ==> false
$CategoryAa1->tree->getParent();     # ==> $CategoryAa
 
// fairly expensive operation follows
$CategoryAa1->tree->getAncestors();  # ==> array($CategoryAa, $CategoryA)
 
// fairly expensive operation follows
$CategoryAa1->tree->getAncestors(1); # ==> array($CategoryAa)

To make this work your model needs a parent_id column (whose name can be overriden with parent_column).

Furthermore you can set the dependent option to automatically delete all children if their parent gets deleted. Otherwise they will become orphants (i.e. have parent_id = NULL)

(Note that on adding a child it will be saved. If the parent has been unsaved until now it will also be saved.)

Configuration options

  • parent_column - specifies the column name to use for keeping the position integer (default: parent_id)
  • dependent - set to true to automatically delete all children when its parent is deleted
  • scope - restricts what is to be considered a list. Given a symbol, it'll attach “_id” (if that hasn't been already) and use that as the foreign key restriction. It's also possible to give it an entire string that is interpolated if you need a tighter scope than just a foreign key.

Example:

actsAsTree(array('scope' => array('todo_list_id = ? AND completed = 0',$todo_list_id)));

More information

 
acts-as-tree.txt · Last modified: 2008/03/13 16:41 by thijs