I am working through the example in Jonathan Rockway's Catalyst book on pp. 43-49 to add a search function to the AddressBook application. Running the sample code from the book (with mods to switch from FormBuilder to FormFu) displays search results, but leaves the wrong URL in the address bar.

Stash Example (see lines 28, 31, 33, 37)
1 package AddressBook::Controller::Search; 2 use strict; 3 use warnings; 4 use Text::CSV_XS; 5 use parent qw(Catalyst::Controller::HTML::FormFu); 6 7 sub search : Global FormConfig { 8 my ($self, $c, $query) = @_; 9 my $form = $c->stash->{form}; 10 11 # Get query from search form 12 if ($form->submitted_and_valid) { 13 $query = $c->request->param('query'); 14 } 15 return unless $query; # No query? We're done 16 $c->stash->{query} = $query; 17 18 # Parse query into tokens 19 my $csv = Text::CSV_XS->new(); 20 $csv->parse($query) or die "Error parsing query"; 21 my @tokens = $csv->fields(); 22 23 # Process query from search form and stash results 24 my $result; 25 if ($form->submitted_and_valid) { 26 if ($c->request->param('domain') eq 'Names') { 27 $result = $c->forward('search_names', \@tokens); 28 $c->stash->{template} = 'search/name_results.tt2'; 29 } else { 30 $result = $c->forward('search_addresses', \@tokens); 31 $c->stash->{template} = 'search/address_results.tt2'; 32 } 33 $c->stash->{result} = $result; 34 my $page = $c->request->param('page'); 35 $page = 1 if ($page !~ /^\d+$/); 36 my $page_result = $result->page($page); 37 $c->stash->{pager} = $page_result->pager; 38 } 39 } 40 41 sub search_names : Private { 42 my ($self, $c, @tokens) = @_; 43 my @people_fields = qw/firstname lastname/; 44 @people_fields = cross(\@people_fields, \@tokens); 45 return $c->model('AddressDB::People')->search(\@people_fields); 46 } 47 48 sub search_addresses : Private { 49 my ($self, $c, @tokens) = @_; 50 my @address_fields = qw/postal phone email location/; 51 @address_fields = cross(\@address_fields, \@tokens); 52 return $c->model('AddressDB::Addresses')->search(\@address_fiel +ds); 53 } 54 55 sub cross { 56 my $columns = shift || []; 57 my $tokens = shift || []; 58 map {s/%/\\%/g} @$tokens; 59 my @result; 60 foreach my $column (@$columns){ 61 push @result, (map +{$column => {-like => "%$_%"}}, @$token +s); 62 } 63 return @result; 64 } 65 66 1;

Previously (pp. 39-40) the book showed how to use sessions to leave the correct URL in the address bar by using redirect as follows:
  $c->response->redirect($c->uri_for('<URL path>'));

This worked fine for the "edit" and "delete" actions previously in the application, but is not working for "search".

I replaced $c->stash->{template} = '<template-name>' with $c->flash->{template} = '<template-name>' and $c->stash->{result} = $result with $c->flash->{result} = $result, and $c->stash->{pager} with $c->flash->{pager}, which generated the following error message from DBIx::Class:
   undef error - Can't call method "select" on an undefined value at: C;/Perl/site/lib/DBIx/Class/ResultSet.pm line 670

Flash Example (see lines 28, 31, 33, 37)
1 package AddressBook::Controller::Search; 2 use strict; 3 use warnings; 4 use Text::CSV_XS; 5 use parent qw(Catalyst::Controller::HTML::FormFu); 6 7 sub search : Global FormConfig { 8 my ($self, $c, $query) = @_; 9 my $form = $c->stash->{form}; 10 11 # Get query from search form 12 if ($form->submitted_and_valid) { 13 $query = $c->request->param('query'); 14 } 15 return unless $query; # No query? We're done 16 $c->stash->{query} = $query; 17 18 # Parse query into tokens 19 my $csv = Text::CSV_XS->new(); 20 $csv->parse($query) or die "Error parsing query"; 21 my @tokens = $csv->fields(); 22 23 # Process query from search form and flash results 24 my $result; 25 if ($form->submitted_and_valid) { 26 if ($c->request->param('domain') eq 'Names') { 27 $result = $c->forward('search_names', \@tokens); 28 $c->flash->{template} = 'search/name_results.tt2'; 29 } else { 30 $result = $c->forward('search_addresses', \@tokens); 31 $c->flash->{template} = 'search/address_results.tt2'; 32 } 33 $c->flash->{result} = $result; 34 my $page = $c->request->param('page'); 35 $page = 1 if ($page !~ /^\d+$/); 36 my $page_result = $result->page($page); 37 $c->flash->{pager} = $page_result->pager; 38 if ($c->request->param('domain') eq 'Names') { 39 $c->response->redirect($c->uri_for('name_results/')); 40 } else { 41 $c->response->redirect($c->uri_for('address_results/')) +; 42 } 43 } 44 } 45 46 sub search_names : Private { 47 my ($self, $c, @tokens) = @_; 48 my @people_fields = qw/firstname lastname/; 49 @people_fields = cross(\@people_fields, \@tokens); 50 return $c->model('AddressDB::People')->search(\@people_fields); 51 } 52 53 sub search_addresses : Private { 54 my ($self, $c, @tokens) = @_; 55 my @address_fields = qw/postal phone email location/; 56 @address_fields = cross(\@address_fields, \@tokens); 57 return $c->model('AddressDB::Addresses')->search(\@address_fiel +ds); 58 } 59 60 sub cross { 61 my $columns = shift || []; 62 my $tokens = shift || []; 63 map {s/%/\\%/g} @$tokens; 64 my @result; 65 foreach my $column (@$columns){ 66 push @result, (map +{$column => {-like => "%$_%"}}, @$token +s); 67 } 68 return @result; 69 } 70 71 1;

I changed flash back to stash for {result} and the DBIx::Class error goes away and the correct URL is displayed in the address bar on the search results page, however no search results are displayed.

It almost seems like a catch-22 situation, where stash is needed for {result} to make DBIx::Class work, but flash is needed for {result} to make $c->response->redirect... work.

I tried using BOTH stash and flash but got the same error I received when using flash only.

Any ideas on how this problem might be resolved?
TIA

"Its not how hard you work, its how much you get done."


In reply to Catalyst: stash vs. flash by roho

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.