[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Omaha.pm] Moose::Meta::Attribute::Native::Trait::Array (mouthful) object sorting by attributes



I have an guest object that stores information.  It has several attributes, including an array of stay history records that are Moose::Meta::Attribute::Native::Trait::Array objects.  I wanted a special handler method on it that always sorted the stay objects in "EndDate" order.  I also needed to display all this info in a Template::Toolkit template.

My Moose config for the "StayHistory" object ended up like this in the parent class:

...
has 'StayHistory' => (               # Moose::Meta::Attribute::Native::Trait::Array
   traits  => ['Array'],                 # of Omni2::Control::OWS::HotelReservation objects
   is      => 'ro',
   isa     => 'ArrayRef[Object]',
   default => sub { [] },
   handles => {
      all_stays    => 'elements',
      add_stay     => 'push',
      map_stays    => 'map',
      filter_stay  => 'grep',
      find_stay    => 'first',
      get_stay     => 'get',
      join_stays   => 'join',
      count_stays  => 'count',
      has_stays    => 'count',
      has_no_stays => 'is_empty',
      sorted_stays => [ sort => sub { $_[1]->EndDate cmp $_[0]->EndDate } ],
   },
);
...

Here's my actual StayHistory Moose attributes, any of which can be sorted on using the above method:

package Omni2::Control::OWS::StayHistory;
use Moose;
has '_twig'              => (is => 'rw', isa => 'Object', required => 1);  # XML::Twig::Elt
has 'site'                => (is => 'rw', isa => 'Str', default=>'OM');
has 'UniqueID'         => (is => 'rw', isa => 'Str');
has 'StartDate'        => (is => 'rw', isa => 'Str');
has 'EndDate'         => (is => 'rw', isa => 'Str');
has 'hotelCode'       => (is => 'rw', isa => 'Str');
has 'Base'              => (is => 'rw', isa => 'Str');
has 'Total'               => (is => 'rw', isa => 'Str');
has 'currencyCode'  => (is => 'rw', isa => 'Str');
has 'ADULT'            => (is => 'rw', isa => 'Str');
has 'CHILD'               => (is => 'rw', isa => 'Str');
...

All I had to do was add a FOREACH in TT and use the "sorted_stays" method above:
...
    [% FOREACH row IN sg.sorted_stays %]
       <tr _onMouseover_="this.bgColor='#FFFFFF'"_onMouseout_="this.bgColor='#F7EDD3'">
          <td>OM</td>
          <td>[% row.UniqueID %]</td>
          <td>[% row.hotelCode %]</td>
          <td>[% row.StartDate %]</td>
          <td>[% row.EndDate %]</td>
          <td>[% row.ADULT %]</td>
          <td>[% row.CHILD %]</td>
          <td>[% row.Base %]</td>
          <td>[% row.Total %]</td>
          <td>[% row.currencyCode %]</td>
       </tr>
    [% END %]
...

Easy!