1 # vim: ts=8:sw=4:sts=4:et
2 package DBIx::Class::Tree::AdjacencyList::Positional;
5 use base qw( DBIx::Class );
8 __PACKAGE__->load_components(qw(
15 DBIx::Class::Tree::AdjacencyList::Positional - Glue DBIx::Class::Positional and DBIx::Class::Tree::AdjacencyList together. (EXPERIMENTAL)
19 Create a table for your tree data.
21 CREATE TABLE employees (
22 employee_id INTEGER PRIMARY KEY AUTOINCREMENT,
23 parent_id INTEGER NOT NULL DEFAULT 0,
24 position INTEGER NOT NULL,
28 In your Schema or DB class add Tree::AdjacencyList::Positional
29 to the top of the component list.
31 __PACKAGE__->load_components(qw( Tree::AdjacencyList::Positional ... ));
33 Specify the column that contains the parent ID and position of each row.
36 __PACKAGE__->parent_column('parent_id');
37 __PACKAGE__->position_column('position');
39 This module provides a few extra methods beyond what
40 L<DBIx::Class::Positional> and L<DBIx::Class::Tree::AdjacencyList>
43 my $parent = $employee->parent();
44 $employee->set_parent( $parent_obj );
45 $employee->set_parent( $parent_id );
47 my $children_rs = $employee->children();
48 my @children = $employee->children();
50 $parent->append_child( $child );
51 $parent->prepend_child( $child );
53 $this->attach_before( $that );
54 $this->attach_after( $that );
58 This module provides methods for working with adjacency lists and positional
59 rows. All of the methods that L<DBIx::Class::Positional> and
60 L<DBIx::Class::Tree::AdjacencyList> provide are available with this module.
67 __PACKAGE__->parent_column('parent_id');
69 Works the same as AdjacencyList's parent_column() method, but it
70 declares the children() has many relationship to be ordered by the
78 my $parent_col = shift;
79 my $primary_col = ($class->primary_columns())[0];
80 $class->belongs_to( '_parent' => $class => { "foreign.$primary_col" => "self.$parent_col" } );
81 $class->has_many( 'children' => $class => { "foreign.$parent_col" => "self.$primary_col" }, { order_by=>$self->position_column() } );
82 $class->_parent_column( $parent_col );
85 return $class->_parent_column();
90 my $parent = $employee->parent();
91 $employee->parent( $parent_obj );
92 $employee->parent( $parent_id );
94 This method overrides AdjacencyList's parent() method but
95 modifies it so that the object is moved to the last position,
96 then the parent is changed, and then it is moved to the last
97 position of the new list.
104 my $new_parent = shift;
105 my $parent_col = $self->_parent_column();
106 if (ref($new_parent)) {
107 $new_parent = $new_parent->id() || croak('Parent object does not have an ID');;
109 return 0 if ($new_parent == ($self->get_column($parent_col)||0));
111 $self->set_column( $parent_col => $new_parent );
113 $self->position_column() =>
114 $self->result_source->resultset->search(
115 {$self->_collection_clause()}
121 return $self->_parent();
126 my $children_rs = $employee->children();
127 my @children = $employee->children();
129 This method works just like it does in the
130 DBIx::Class::Tree::AdjacencyList module except it
131 orders the children by there position.
135 $parent->append_child( $child );
137 Sets the child to have the specified parent and moves the
138 child to the last position.
143 my( $self, $child ) = @_;
144 $child->parent( $self );
149 $parent->prepend_child( $child );
151 Sets the child to have the specified parent and moves the
152 child to the first position.
157 my( $self, $child ) = @_;
158 $child->parent( $self );
159 $child->move_first();
164 $this->attach_before( $that );
166 Attaches the object at the position just before the
167 calling object's position.
172 my( $self, $sibling ) = @_;
173 $sibling->parent( $self->parent() );
174 $sibling->move_to( $self->get_column($self->position_column()) );
179 $this->attach_after( $that );
181 Attaches the object at the position just after the
182 calling object's position.
187 my( $self, $sibling ) = @_;
188 $sibling->parent( $self->parent() );
189 $sibling->move_to( $self->get_column($self->position_column()) + 1 );
192 =head1 PRIVATE METHODS
194 These methods are used internally. You should never have the
197 =head2 collection_column
199 Postional's collection_column method does not, and should not, be
200 defined when using this module. This method just throws out an
201 error if you try to use it.
205 sub collection_column {
206 croak('Use parent_column() instead of collection_column()');
209 =head2 _collection_clause
211 This method is provided as an override of the method in
212 L<DBIx::Class::Positional>. This method is what provides the
213 glue between AdjacencyList and Positional.
217 sub _collection_clause {
220 $self->_parent_column() =>
221 $self->get_column($self->_parent_column())
230 Aran Clary Deltac <bluefeet@cpan.org>
234 You may distribute this code under the same terms as Perl itself.