1 # vim: ts=8:sw=4:sts=4:et
2 package DBIx::Class::Tree::AdjacencyList::Ordered;
5 use base qw( DBIx::Class );
8 __PACKAGE__->load_components(qw(
15 DBIx::Class::Tree::AdjacencyList::Ordered - Glue DBIx::Class::Ordered and DBIx::Class::Tree::AdjacencyList together. (EXPERIMENTAL)
19 Create a table for your tree data.
22 item_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::Ordered
29 to the top of the component list.
31 __PACKAGE__->load_components(qw( Tree::AdjacencyList::Ordered ... ));
33 Specify the column that contains the parent ID and position of each row.
36 __PACKAGE__->position_column('position');
37 __PACKAGE__->parent_column('parent_id');
39 This module provides a few extra methods beyond what
40 L<DBIx::Class::Ordered> and L<DBIx::Class::Tree::AdjacencyList>
43 my $parent = $item->parent();
44 $item->parent( $parent_obj );
45 $item->parent( $parent_id );
47 my $children_rs = $item->children();
48 my @children = $item->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 ordered
59 rows. All of the methods that L<DBIx::Class::Ordered> and
60 L<DBIx::Class::Tree::AdjacencyList> provide are available with this module.
66 __PACKAGE__->parent_column('parent_id');
68 Works the same as AdjacencyList's parent_column() method, but it
69 declares the children() has many relationship to be ordered by the
77 my $parent_col = shift;
78 my $primary_col = ($class->primary_columns())[0];
79 my $position_col = $class->position_column() || croak('You must call position_column() before calling parent_column()');
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=>$position_col } );
82 $class->_parent_column( $parent_col );
85 return $class->_parent_column();
90 my $parent = $item->parent();
91 $item->parent( $parent_obj );
92 $item->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, thus maintaining the intergrity of
105 my $new_parent = shift;
106 my $parent_col = $self->_parent_column();
107 if (ref($new_parent)) {
108 $new_parent = $new_parent->id() || croak('Parent object does not have an ID');;
110 return 0 if ($new_parent == ($self->get_column($parent_col)||0));
112 $self->set_column( $parent_col => $new_parent );
114 $self->position_column() =>
115 $self->result_source->resultset->search(
116 {$self->_grouping_clause()}
122 return $self->_parent();
127 my $children_rs = $item->children();
128 my @children = $item->children();
130 This method works just like it does in the
131 DBIx::Class::Tree::AdjacencyList module except it
132 orders the children by there position.
136 $parent->append_child( $child );
138 Sets the child to have the specified parent and moves the
139 child to the last position.
144 my( $self, $child ) = @_;
145 $child->parent( $self );
150 $parent->prepend_child( $child );
152 Sets the child to have the specified parent and moves the
153 child to the first position.
158 my( $self, $child ) = @_;
159 $child->parent( $self );
160 $child->move_first();
165 $this->attach_before( $that );
167 Attaches the object at the position just before the
168 calling object's position.
173 my( $self, $sibling ) = @_;
174 $sibling->parent( $self->parent() );
175 $sibling->move_to( $self->get_column($self->position_column()) );
180 $this->attach_after( $that );
182 Attaches the object at the position just after the
183 calling object's position.
188 my( $self, $sibling ) = @_;
189 $sibling->parent( $self->parent() );
190 $sibling->move_to( $self->get_column($self->position_column()) + 1 );
193 =head1 PRIVATE METHODS
195 These methods are used internally. You should never have the
198 =head2 grouping_column
200 Postional's grouping_column method does not, and should not, be
201 defined when using this module. This method just throws out an
202 error if you try to use it.
206 sub grouping_column {
207 croak('Use parent_column() instead of grouping_column()');
210 =head2 _grouping_clause
212 This method is provided as an override of the method in
213 L<DBIx::Class::Ordered>. This method is what provides the
214 glue between AdjacencyList and Ordered.
218 sub _grouping_clause {
220 my $col = $self->_parent_column();
222 $col => $self->get_column( $col )
231 Aran Clary Deltac <bluefeet@cpan.org>
235 You may distribute this code under the same terms as Perl itself.