From 6e25f5ebaf82b5d17221e65363c0606853ed26e4 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Tue, 5 Mar 2013 13:13:01 +0100 Subject: [PATCH] ActsAsList: get_next_in_list() und get_previous_in_list() --- SL/DB/Helper/ActsAsList.pm | 47 +++++++++++++++++++++++++++++++++++++- t/db_helper/acts_as_list.t | 11 +++++++-- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/SL/DB/Helper/ActsAsList.pm b/SL/DB/Helper/ActsAsList.pm index f5bc8c293..566422a9d 100644 --- a/SL/DB/Helper/ActsAsList.pm +++ b/SL/DB/Helper/ActsAsList.pm @@ -3,7 +3,8 @@ package SL::DB::Helper::ActsAsList; use strict; use parent qw(Exporter); -our @EXPORT = qw(move_position_up move_position_down add_to_list remove_from_list reorder_list configure_acts_as_list); +our @EXPORT = qw(move_position_up move_position_down add_to_list remove_from_list reorder_list configure_acts_as_list + get_previous_in_list get_next_in_list); use Carp; @@ -112,6 +113,16 @@ SQL return $self->db->in_transaction ? $worker->() : $self->db->do_transaction($worker); } +sub get_next_in_list { + my ($self) = @_; + return get_previous_or_next($self, 'next'); +} + +sub get_previous_in_list { + my ($self) = @_; + return get_previous_or_next($self, 'previous'); +} + sub reorder_list { my ($class_or_self, @ids) = @_; @@ -245,6 +256,30 @@ SQL $self->update_attributes($column => $new_position); } +sub get_previous_or_next { + my ($self, $direction) = @_; + + my $asc_desc = $direction eq 'next' ? 'ASC' : 'DESC'; + my $comparator = $direction eq 'next' ? '>' : '<'; + my $table = $self->meta->table; + my $column = column_name($self); + my $primary_key_col = ($self->meta->primary_key)[0]; + my ($group_by, @values) = get_group_by_where($self); + $group_by = " AND ${group_by}" if $group_by; + my $sql = <db->dbh->selectrow_arrayref($sql, undef, $self->$column, @values) || [])->[0]; + + return $id ? $self->_get_manager_class->find_by(id => $id) : undef; +} + sub column_name { my ($self) = @_; my $column = get_spec(ref $self, 'column_name'); @@ -372,6 +407,16 @@ saved to the database. Sets this items positional column to C<-1>, saves it and moves all following items up by 1. +=item C + +Fetches the previous item in the list. Returns C if C<$self> is +already the first one. + +=item C + +Fetches the next item in the list. Returns C if C<$self> is +already the last one. + =item C Re-orders the objects given in C<@ids> by their position in C<@ids> by diff --git a/t/db_helper/acts_as_list.t b/t/db_helper/acts_as_list.t index 1262353c6..0d47bb253 100644 --- a/t/db_helper/acts_as_list.t +++ b/t/db_helper/acts_as_list.t @@ -1,4 +1,4 @@ -use Test::More tests => 44; +use Test::More tests => 50; use Test::Exception; use strict; @@ -206,7 +206,14 @@ reset_state(); $item = get_item(8); $item->remove_from_list; $item->parent_id(3); $item->add_to_list(position => 'first'); test_positions "add_to_list position 'first' in empty", [ 1, undef, 1 ], [ 2, undef, 2 ], [ 3, 1, 1 ], [ 4, 1, 2 ], [ 5, 1, 3 ], [ 6, 4, 1 ], [ 7, 4, 2 ], [ 8, 3, 1 ]; - +reset_state(); +$item = get_item(4); +is($item->get_next_in_list->id, 5, 'Next of 4 is 5'); +is($item->get_previous_in_list->id, 3, 'Previous of 4 is 5'); +is($item->get_next_in_list->get_previous_in_list->id, 4, 'Previous of Next of 4 is 4'); +is($item->get_previous_in_list->get_next_in_list->id, 4, 'Next of Previous of 4 is 4'); +is($item->get_next_in_list->get_next_in_list, undef, 'Next of Next of 4 is undef'); +is($item->get_previous_in_list->get_previous_in_list, undef, 'Previous of Previous of 4 is undef'); # Parametervalidierung throws_ok { new_item()->move_position_up } qr/not.*been.*saved/i, 'move up not saved yet'; -- 2.20.1