How to access session data in the Moholic model

Below is an example of a Mojolicious application (6.14) ... Sorry for the $ _ [0] and other less-than-best practices; I tried to make it compact.

package ScopeTest;
use Mojo::Base 'Mojolicious';

sub startup {
  my $app = shift;

  $app->helper( hello    => sub { "Hello!" } );
  $app->helper( username => sub { $_[0]->session('username'); } );
  $app->helper( model    => sub { ScopeTest::Model->new( app => $_[0]->app ) } );
  $app->helper( hasPerm  => sub { $_[0]->model->hasPerm( @_ ) } );

  $app->routes->get('/alice')->to('controller#alice');
  $app->routes->get('/carol')->to('controller#carol');
  $app->routes->get('/steve')->to('controller#steve');
}

##############################
package ScopeTest::Controller;
use Mojo::Base 'Mojolicious::Controller';

sub alice { $_[0]->session( username => "alice" ); $_[0]->render_message() }
sub carol { $_[0]->session( username => "carol" ); $_[0]->render_message() }
sub steve { $_[0]->session( username => "steve" ); $_[0]->render( text =>
    sprintf "%s: %s\n", $_[0]->username, $_[0]->model->update_db ? 'Okay' : 'Fail' ) }

sub render_message { $_[0]->render( text =>
    sprintf "%s: %s\n", $_[0]->username, $_[0]->hasPerm('canLogin') ? 'Okay' : 'Fail' ) }

##############################
package ScopeTest::Model;
use Mojo::Base -base;

has 'app';

my %perms = ( alice => [ qw{ canLogin } ],
              carol => [ ],
              steve => [ qw{ canUpdateDB } ] );

sub hasPerm {
    my ( $self, $perm ) = @_;
    no warnings 'uninitialized';

    $self->app->log->debug("app->hello            = " . $self->app->hello                 );   # OKAY
    $self->app->log->debug("app->username         = " . $self->app->username              );   # FAILS
    $self->app->log->debug("session('username')   = " . $self->app->session('username')   );   # FAILS
    $self->app->log->debug("session->{'username'} = " . $self->app->session->{'username'} );   # FAILS

    my $username;   # = $self->app->username;
    return grep { $_ eq $perm } @{ $perms{$username} };
}

sub update_db {
    my ( $self, $data ) = @_;
    $self->hasPerm('canUpdateDB') or return;
    # else ...
    return 1;
}

1;

      

Although things like $self->app->log->debug()

that $self->app->dumper()

, and other helpers do the right thing, $self->app->session

does not.

I know the transition to $app

is considered less ideal, but I would expect the above to be at least WORK ...

In short, the username is repeated over and over again (this is a toy example: a real application has dozens of different methods that sometimes call each other, etc.) is there a cleaner way to access session data from the model class

PS. And before you say it Model->new(username => $self->session('username')

, that means knowing, a priori , which session variables I need and listing them all in the constructor and attribute lists; I was hoping that if I just went through in general $app

(or even $app->session

) I could keep things going in the future.

Thank!

+3


source to share


1 answer


The error I was making was: the "session" information is not application related; it is associated with the controller:

$app->helper( model => sub { ScopeTest::Model->new( ctrl => $_[0] ) } );

      

then



package ScopeTest::Model;
use Mojo::Base -base;

has 'ctrl';

...
$self->ctrl->app->log->debug("username = " . $self->ctrl->username );

      

Yes, I know it's still not optimal enough to pass the Model Controller, but that at least explains why I couldn't get it to work in EVERYTHING before ...

+1


source







All Articles