<div dir="ltr">Hi Richard - not sure mine is the most elegant approach vis a vi plugins - but it is working, and it is fast :)  For production I'm running multiple instances of Dancer with shared memcached for session management, all behind balance.  This is all on a 12-core OS X Mavericks box and barely makes a blip on utilization.<div><br></div><div>1) I generated all the Rose::DB::Object classes from the MySQL schema for the RDBO classes and Manager classes.</div><div><br></div><div>2) I wrote a few helper functions to convert DBO objects in hash or array of hash suitable for Dancer templating (I'll copy those in below).  I still use HTML::Template over TT just so that I can have non-coder HTML designers work with the templates, so these data structures work for that template engine.  The result is a route that looks like this:</div><div><br></div><div><div><font face="courier new, monospace">#----------------------------------------------------------------------</font></div><div><font face="courier new, monospace">get '/modal/points/:student_id' => sub {</font></div><div><font face="courier new, monospace">#----------------------------------------------------------------------</font></div><div><font face="courier new, monospace">   my $student = NDB::Student->new( id => params->{student_id} )->load;</font></div><div><font face="courier new, monospace">   my $rv = dbo2h($student);</font></div><div><font face="courier new, monospace">   template "staff/modal/points", $rv, {layout => "simple"};</font></div><div><font face="courier new, monospace">};</font></div></div><div><br></div><div>Here are a few other sample routes:</div><div><br></div><div><div><font face="courier new, monospace">#----------------------------------------------------------------------</font></div><div><font face="courier new, monospace">post '/studio' => sub {</font></div><div><font face="courier new, monospace">#----------------------------------------------------------------------</font></div><div><font face="courier new, monospace">   my @fields = ( qw( studio_name campus_id location session_rate</font></div><div><font face="courier new, monospace">                      calendar_id ) );</font></div><div><font face="courier new, monospace">   dbo_add_update("NDB::Studio", { params }, \@fields );</font></div><div><font face="courier new, monospace">   redirect "/admin/campus";</font></div><div><font face="courier new, monospace">};</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">#----------------------------------------------------------------------</font></div><div><font face="courier new, monospace">post '/studio/delete' => sub {</font></div><div><font face="courier new, monospace">#----------------------------------------------------------------------</font></div><div><font face="courier new, monospace">   my $p = NDB::Studio->new( id => params->{id} );</font></div><div><font face="courier new, monospace">   if ( params->{id} == params->{confirm_id} ) {</font></div><div><font face="courier new, monospace">      $p->delete;</font></div><div><font face="courier new, monospace">   }</font></div><div><font face="courier new, monospace">   redirect "/admin/campus";</font></div><div><font face="courier new, monospace">};</font></div></div><div><br></div><div>I also have some other helpers that follow RDBO relationships and inflate the data structures for templating:</div><div><br></div><div><div><font face="courier new, monospace">#----------------------------------------------------------------------</font></div><div><font face="courier new, monospace">get '/campus' => sub {</font></div><div><font face="courier new, monospace">#----------------------------------------------------------------------</font></div><div><font face="courier new, monospace">   my $campuses = NDB::Campus::Manager->get_campus();</font></div><div><font face="courier new, monospace">   my $rv = dbom2aoh( $campuses, { studios   => 'studio_list',</font><span style="font-family:'courier new',monospace"> staff => 'staff_list', } );</span></div><div><font face="courier new, monospace">   template "admin/campus", { campus_list => $rv, add_navbar() }, { layout => 'staff'};</font></div><div><font face="courier new, monospace">};</font></div></div><div><br></div><div><br></div><div>3) The helper functions help glue Dancer and RDBO together:</div><div><br></div><div><div><br></div><div><font face="courier new, monospace">=head2 dbo2h()</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">dbo2h - convert a DBO object into a hash of key/value pairs.</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">   my $hashref = dbo2h( $dboobject, $date_format_string, $expandhash, $prepend );</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">=cut</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">sub dbo2h {</font></div><div><font face="courier new, monospace">   my $row = shift;</font></div><div><font face="courier new, monospace">   my $date_format = shift || '%Y-%m-%d %T';</font></div><div><font face="courier new, monospace">   my $expand = shift;</font></div><div><font face="courier new, monospace">   my $prepend = shift;</font></div><div><font face="courier new, monospace">   my $parent_prepend = shift;</font></div><div><font face="courier new, monospace">   my %hash = $row->column_value_pairs;</font></div><div><font face="courier new, monospace">   foreach my $key ( keys %$expand ) {</font></div><div><font face="courier new, monospace">      my $reln = $expand->{$key};</font></div><div><font face="courier new, monospace">      if ( $prepend ) {</font></div><div><font face="courier new, monospace">         $hash{$reln . '_' . $key} = ( $row->$reln ? $row->$reln->$key : '' );</font></div><div><font face="courier new, monospace">      } else {</font></div><div><font face="courier new, monospace">         $hash{$key} =  ( $row->$reln ? $row->$reln->$key : '');</font></div><div><font face="courier new, monospace">      }</font></div><div><font face="courier new, monospace">   }</font></div><div><font face="courier new, monospace">   foreach my $key ( keys %hash ) {</font></div><div><font face="courier new, monospace">      if ( ref $hash{$key} eq 'DateTime' ) {</font></div><div><font face="courier new, monospace">         $hash{$key} = $hash{$key}->strftime($date_format);</font></div><div><font face="courier new, monospace">      }</font></div><div><font face="courier new, monospace">      elsif ( ref $hash{$key} eq 'Time::Clock' ) {</font></div><div><font face="courier new, monospace">         $hash{$key} = $hash{$key}->as_string;</font></div><div><font face="courier new, monospace">      }</font></div><div><font face="courier new, monospace">      $hash{$key} =~ s/\s+$//g;</font></div><div><font face="courier new, monospace">      if ( $parent_prepend ) {</font></div><div><font face="courier new, monospace">         $hash{$parent_prepend.'_'.$key} = delete $hash{$key};</font></div><div><font face="courier new, monospace">      }</font></div><div><font face="courier new, monospace">   }</font></div><div><font face="courier new, monospace">   return \%hash;</font></div><div><font face="courier new, monospace">}</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">=head2 dbo2aoh()</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">dbo2aoh - convert a DBO set of objects into an array of hash of key/value pairs.</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">   my $arrayref = dbo2aoh( $dboarray, $date_format_string, $expandhash, $prepend );</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">=cut</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">sub dbo2aoh {</font></div><div><font face="courier new, monospace">   my $rows = shift;</font></div><div><font face="courier new, monospace">   my $date_format = shift;</font></div><div><font face="courier new, monospace">   my $expandhash = shift;</font></div><div><font face="courier new, monospace">   my $prepend = shift;</font></div><div><font face="courier new, monospace">   my $parent_prepend = shift;</font></div><div><font face="courier new, monospace">   my @results;</font></div><div><font face="courier new, monospace">   foreach my $row ( @$rows ) {</font></div><div><font face="courier new, monospace">      push(@results, dbo2h( $row, $date_format, $expandhash, $prepend, $parent_prepend ) );</font></div><div><font face="courier new, monospace">   }</font></div><div><font face="courier new, monospace">   return \@results;</font></div><div><font face="courier new, monospace">}</font></div></div><div><font face="courier new, monospace"><br></font></div><div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">=head2 dbo_add_update()</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">dbo_add_update - convert Dancer params into DBO add/update</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">   my @fields = ( qw( field1 field2 field3 ) );</font></div><div><font face="courier new, monospace">   @errors = dbo_update( 'NDB::Lecture', { params }, \@fields, );</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">=cut</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">sub dbo_add_update {</font></div><div><font face="courier new, monospace">   my ( $class, $p, $fields ) = @_;</font></div><div><font face="courier new, monospace">   my ( $obj, @errors );</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">   if ( $p->{id} ) {</font></div><div><font face="courier new, monospace">      $obj = $class->new( id => $p->{id} );</font></div><div><font face="courier new, monospace">      push(@errors, "No such record") unless $obj->load_speculative;</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">      unless ( @errors ) {</font></div><div><font face="courier new, monospace">         foreach my $field ( @$fields ) {</font></div><div><font face="courier new, monospace">            $obj->$field( $p->{$field} ) if exists $p->{$field};</font></div><div><font face="courier new, monospace">         }</font></div><div><font face="courier new, monospace">         $obj->save;</font></div><div><font face="courier new, monospace">      }</font></div><div><font face="courier new, monospace">   } else {</font></div><div><font face="courier new, monospace">      my %columns;</font></div><div><font face="courier new, monospace">      foreach my $field ( @$fields ) {</font></div><div><font face="courier new, monospace">        $columns{$field} = $p->{$field} if exists $p->{$field};</font></div><div><font face="courier new, monospace">      }</font></div><div><font face="courier new, monospace">      $obj = $class->new( %columns );</font></div><div><font face="courier new, monospace">      $obj->save;</font></div><div><font face="courier new, monospace">   }</font></div><div><font face="courier new, monospace">   return $obj;</font></div><div><font face="courier new, monospace">}</font></div></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"><div>=head2 dbom2aoh()</div><div><br></div><div>dbom2row - convert dbo to AOH and add DBOM relationships as child AOH</div><div><br></div><div>   $rv = dbo_update( $dbo, { relationship => 'hash_key' }, $date_format_string, $expandhash, $prepend );</div><div><br></div><div>=cut</div><div><br></div><div>sub dbom2aoh {</div><div>   my ( $parent, $map, $dateformat, $expand, $prepend ) = @_;</div><div>   my @rv;</div><div>   foreach my $dbo ( @$parent ) {</div><div>      my $row = dbo2h( $dbo, $dateformat, $expand, $prepend );</div><div>      foreach my $reln ( keys %$map ) {</div><div>         my $children = $dbo->$reln;</div><div>         $row->{ $map->{$reln} } = dbo2aoh( $children, $dateformat );</div><div>      }</div><div>      push @rv, $row;</div><div>   }</div><div>   return \@rv;</div><div>}</div></font></div><div><br></div><div>Like I said in my initial post - I'm sure there are refactor opportunities in my code - so please be kind :)  I tried to go for readability over conciseness so that I could hand it off at some point.</div><div><br></div><div>Hope that helps.</div><div><br></div><div>Best,</div><div><br></div><div>Mike.</div><div><br></div><div class="gmail_extra"><div><div dir="ltr"><div><br></div></div></div>
<br><div class="gmail_quote">On Wed, Sep 10, 2014 at 12:19 PM, Richard Jones <span dir="ltr"><<a href="mailto:ra.jones@dpw.clara.co.uk" target="_blank">ra.jones@dpw.clara.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
  
    
  
  <div bgcolor="#FFFFFF" text="#000000">
    Hello Mike,<br>
    <br>
    I was very interested to read about your experience. I'm not touting
    for the job as I have a full-time job already. But just to say I'm a
    recent convert to Dancer2 from developing long-term with
    CGI::Application/RBDO/MySQL. I'm most interested in how you
    integrated Rose with Dancer. I haven't tried it yet as all my recent
    apps are small enough to use DBIx::Simple, but I'm planning a bigger
    one that will need an ORM. Do you use the MVC architecture? Do you
    use an adapter class for Rose or just rely on the Dancer DB plugin?
    Is your project open source or are you not able to expose the code
    base publicly?<br>
    <br>
    Good luck recruiting.<div><div class="h5"><br>
    <br>
    <div>On 10/09/2014 19:39, Mike Schroeder
      wrote:<br>
    </div>
    </div></div><blockquote type="cite"><div><div class="h5">
      <div dir="ltr">
        <div>
          <div dir="ltr">
            <div>Hi all - I've been using Dancer for years and have
              watched this list for years - thank you to everyone for a
              great framework.</div>
            <div><br>
            </div>
            <div>In my new role at a new company (an audio engineering
              and production school), I searched for an off the shelf
              system to do what I wanted, and finally gave up and wrote
              my own.  Dancer, Rose::DB::Object, Bootstrap and MySQL -
              amazing what you can do in 3-4 months of spare time :)</div>
            <div><br>
            </div>
            <div>The project is up and in production, running well, and
              now we are wanting to add more features, etc.  I am too
              busy doing my real job (CEO) to have the time to do the
              development work on the system.</div>
            <div><br>
            </div>
            <div>I'm looking for someone who can can SSH into our
              servers from anywhere, work within my existing
              architecture to extend and add features, refactor some of
              my prototype code (it's not horrible, but I know it could
              be better), and help move the project forward.</div>
            <div><br>
            </div>
            <div>The ideal candidate would have experience with Dancer,
              Rose::DB::Object, Bootstrap and MySQL.  There is also a
              POE-based daemon using Rose::DB::Object running alongside
              for long-running asynchronous job handling, so POE
              experience would be helpful as well. </div>
            <div><br>
            </div>
            <div>This is not a full-time job - more project based work
              to add new features, etc.  I expect to keep building this
              out over the next year, so I'm looking for a good long
              term partner to work with. I'm ok with different
              timezones, as long as we can find some common time for
              Skype etc. (I'm in Vancouver, so Pacific Timezone).</div>
            <div><br>
            </div>
            <div>If you are interested, you can send an email to mike at
              nimbusrecording dot com.  Let me know your experience and
              expectations for payment.</div>
            <div><br>
            </div>
            <div>Thanks all - I really appreciate the Dancer community
              and what it allows us all to create.</div>
            <div><br>
            </div>
            <div>Best,</div>
            <div><br>
            </div>
            <div>Mike.</div>
            <div><br>
            </div>
          </div>
        </div>
      </div>
      <br>
      <fieldset></fieldset>
      <br>
      </div></div><pre>_______________________________________________
dancer-users mailing list
<a href="mailto:dancer-users@dancer.pm" target="_blank">dancer-users@dancer.pm</a>
<a href="http://lists.preshweb.co.uk/mailman/listinfo/dancer-users" target="_blank">http://lists.preshweb.co.uk/mailman/listinfo/dancer-users</a><span class=""><font color="#888888">
</font></span></pre><span class=""><font color="#888888">
    </font></span></blockquote><span class=""><font color="#888888">
    <br>
    <pre cols="72">-- 
Richard Jones</pre>
  </font></span></div>

<br>_______________________________________________<br>
dancer-users mailing list<br>
<a href="mailto:dancer-users@dancer.pm">dancer-users@dancer.pm</a><br>
<a href="http://lists.preshweb.co.uk/mailman/listinfo/dancer-users" target="_blank">http://lists.preshweb.co.uk/mailman/listinfo/dancer-users</a><br>
<br></blockquote></div><br></div></div>