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
);
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();
=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(
$self->update();
return 1;
}
- else {
- return $self->next::method();
- }
+ return $self->_parent();
}
=head2 children
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 );
sub _collection_clause {
my( $self ) = @_;
return (
- $self->parent_column() =>
- $self->get_column($self->parent_column())
+ $self->_parent_column() =>
+ $self->get_column($self->_parent_column())
);
}