Richard Jones wrote:
In the following example code, which uses CAP::RunmodeDeclare for
runmode handling:
#-----------------------------------------------------------------------
runmode edit ($id) {
my $errs = shift;
$id || return $self->error('no id passed to edit'); # warn 'id:'.$id;
my $data = $self->model->get_some_data($id);
[ .. ]
return $self->tt_process($errs);
}
#-----------------------------------------------------------------------
runmode update ($id) {
# if param 'id' passed, return error to edit():
my $error_rm = $id ? 'edit' : 'default';
my $dfv = $self->check_rm( $error_rm, '_update_validate_profile' )
|| return $self->dfv_error_page;
[ .. ]
}
A url of '/myapp/update/1' via CA::Dispatch calls the 'update' runmode,
which captures the param '1' into the var $id. All works as advertised.
But if validation in update() fails, the 'update' runmode is required to
return the dfv error page for 'edit', but it doesn't, instead a fatal
error results from the consequence of edit() capturing the value of dfv
errors in $id, which then kills the model method as it tries to execute
an sql statement using the dfv errors hashref instead of an id value.
The problem seems to be that, according to the docs, RunmodeDeclare will
capture variables passed as $self->baz(1, "me") as well as from the
query object. So 'edit ($id)' means $id will capture anything passed
into the rm. What seems odd is that the dfv errors hashref is also
captured in the first arg shifted from @_:
That's the issue: the arguments aren't shifted off @_, they're assigned from
it. CAP::RD rewrites this:
runmode something ($some, $variables)
into this:
sub something {
my $self = shift;
my ($some, $variables) = @_;
$some = $self->query->param('some') unless defined $some;
$some = $self->param('some') unless defined $some;
...
In other words, it tries treating the signature as a regular method signature
first, and only falls back to looking in $self->query or $self->param if the
variables are still undefined.
And it also explains why you got the errs hashref in both $id and $errs, since
@_ is still unchanged.
runmode edit ($id) {
my $errs = shift;
warn Dumper $id; # contains the dfv errors hashref
warn Dumper $errs; # also contains the dfv errors hashref !!
[ .. ]
}
Of course it all works fine if I switch back to conventional runmode
handling, or to AutoRunmode.
The other solution would be to recognise that dfv_error_page passes the dfv
hashref as the first argument, and name that in your signature:
runmode edit ($errs, $id) { ...
That way, $errs is picked up from @_, while $id is picked up from either
$self->query or $self->param (provided dfv_error_page doesn't pass additional
parameters).
HTH,
Rhesa
##### CGI::Application community mailing list ################
## ##
## To unsubscribe, or change your message delivery options, ##
## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp ##
## ##
## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ##
## Wiki: http://cgiapp.erlbaum.net/ ##
## ##
################################################################