Tests for adjacency list as well as a bunch of fixes.
[dbsrgits/DBIx-Class-Tree.git] / lib / DBIx / Class / Tree / AdjacencyList / Positional.pm
index ebe0f85..7112ad2 100644 (file)
@@ -20,7 +20,7 @@ Create a table for your tree data.
 
   CREATE TABLE employees (
     employee_id INTEGER PRIMARY KEY AUTOINCREMENT,
-    parent_id INTEGER NOT NULL,
+    parent_id INTEGER NOT NULL DEFAULT 0,
     position INTEGER NOT NULL,
     name TEXT NOT NULL
   );
@@ -34,15 +34,15 @@ Specify the column that contains the parent ID and position of each row.
 
   package My::Employee;
   __PACKAGE__->parent_column('parent_id');
-  __PACAKGE__->position_column('position');
+  __PACKAGE__->position_column('position');
 
 This module provides a few extra methods beyond what 
 L<DBIx::Class::Positional> and L<DBIx::Class::Tree::AdjacencyList> 
 already provide.
 
   my $parent = $employee->parent();
-  $employee->parent( $parent_obj );
-  $employee->parent( $parent_id );
+  $employee->set_parent( $parent_obj );
+  $employee->set_parent( $parent_id );
   
   my $children_rs = $employee->children();
   my @children = $employee->children();
@@ -62,32 +62,53 @@ If you
 
 =head1 METHODS
 
+=head2 parent_column
+
+  __PACKAGE__->parent_column('parent_id');
+
+Works the same as AdjacencyList's parent_column() method, but it 
+declares the children() has many relationship to be ordered by the 
+position column.
+
+=cut
+
+sub parent_column {
+    my $class = shift;
+    if (@_) {
+        my $parent_col = shift;
+        my $primary_col = ($class->primary_columns())[0];
+        $class->belongs_to( '_parent' => $class => { "foreign.$primary_col" => "self.$parent_col" } );
+        $class->has_many( 'children' => $class => { "foreign.$parent_col" => "self.$primary_col" }, { order_by=>$self->position_column() } );
+        $class->_parent_column( $parent_col );
+        return 1;
+    }
+    return $class->_parent_column();
+}
+
 =head2 parent
 
   my $parent = $employee->parent();
   $employee->parent( $parent_obj );
   $employee->parent( $parent_id );
-  
-  my $children_rs = $employee->children();
-  my @children = $employee->children();
 
-This method works exactly like it does in the 
-DBIx::Class::Tree::AdjacencyList module except that it will 
-first move the object to the last position of the list, change 
-the parent ID, then move the object to the last position of 
-the new list.  This ensures the intergrity of the positions.
+This method overrides AdjacencyList's parent() method but 
+modifies it so that the object is moved to the last position, 
+then the parent is changed, and then it is moved to the last 
+position of the new list.
 
 =cut
 
 sub parent {
-    my( $self, $new_parent ) = @_;
-    if ($new_parent) {
+    my $self = shift;
+    if (@_) {
+        my $new_parent = shift;
+        my $parent_col = $self->_parent_column();
         if (ref($new_parent)) {
-            $new_parent = $new_parent->id() || croak('Parent object does not have an id');
+            $new_parent = $new_parent->id() || croak('Parent object does not have an ID');;
         }
-        return 0 if ($new_parent == ($self->get_column($self->parent_column())||0));
-        $self->move_last();
-        return 0 if (!$self->next::method( $new_parent ));
+        return 0 if ($new_parent == ($self->get_column($parent_col)||0));
+        $self->move_last;
+        $self->set_column( $parent_col => $new_parent );
         $self->set_column(
             $self->position_column() => 
                 $self->result_source->resultset->search(
@@ -97,9 +118,7 @@ sub parent {
         $self->update();
         return 1;
     }
-    else {
-        return $self->next::method();
-    }
+    return $self->_parent();
 }
 
 =head2 children
@@ -111,18 +130,6 @@ This method works just like it does in the
 DBIx::Class::Tree::AdjacencyList module except it 
 orders the children by there position.
 
-=cut
-
-sub children {
-    my( $self ) = @_;
-    my $rs = $self->result_source->resultset->search(
-        { $self->parent_column() => $self->id() },
-        { order_by => $self->position_column() }
-    );
-    return $rs->all() if (wantarray());
-    return $rs;
-}
-
 =head2 append_child
 
   $parent->append_child( $child );
@@ -210,8 +217,8 @@ glue between AdjacencyList and Positional.
 sub _collection_clause {
     my( $self ) = @_;
     return (
-        $self->parent_column() =>
-        $self->get_column($self->parent_column())
+        $self->_parent_column() =>
+        $self->get_column($self->_parent_column())
     );
 }