使用Mojo :: Base从模块访问Mojolicious助手?

Vir*_*olf 3 perl mojolicious

我有一个现有的应用程序(我的网站),正在整理一些代码,整理后的想法与此处Mojo::Pg示例相同,只是使用单独的模型和控制器文件来保持定义。我的网站访问Flickr和Last.fm的API,并且在中定义了一个帮助器:Site::Helpers

$app->helper(
    get_base_rest_url => sub {
        my ( $self, $config ) =  @_;

        sswitch ( $config ) {
            case 'photos': {
                my $base_url = 'https://api.flickr.com/services/rest/';
                my $user_id  = '7281432@N05';
                my $api_key  = $self->app->config->{ 'api_token' }{ 'flickr' };

                my $url =
                    "$base_url"
                    . "?user_id=$user_id"
                    . "&api_key=$api_key"
                    . "&per_page=" . $self->session->{ per_page }
                    . '&format=json'
                    . '&nojsoncallback=1';

                return $url;
            }

            case 'music': {
                my $base_url = 'https://ws.audioscrobbler.com/2.0/';
                my $username = 'virtualwolf';
                my $api_key  = $self->app->config->{ 'api_token' }{ 'last_fm' };
                my $per_page = $self->session->{ 'per_page' };

                my $url = "$base_url?user=$username&limit=$per_page&api_key=$api_key&format=json";

                return $url;
            }
        }
    }
);
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是我不知道如何从Site::Model::Photos模块访问该帮助程序。错误是

Can't locate object method "get_base_rest_url" via package "Site::Model::Photos"
Run Code Online (Sandbox Code Playgroud)

这足够公平,但是我无法弄清楚如何真正获得该get_base_rest_url帮助程序(或者,如何访问api_token配置)。

Log*_*niz 5

问题是您的模块没有获取访问您应用程序的应用程序属性/方法。

因此,当您创建实例时,Site::Model::Photos需要app在参数中传递给它,并使其减弱诸如此类的效果:

package Site::Model::Photos
use Scalar::Util 'weaken';
sub new {
  my $class = shift;
  my $app = shift;
  my $hash = {app => $app, ...};
  weaken $hash->{app};
  return bless $hash, $class;
}

sub your_method {
  my $self = shift;
  $self->{app}->get_base_rest_url(...);
}

1;
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用此模块https://metacpan.org/release/Mojolicious-Plugin-Model为您执行以下操作:

package Site::Model::Photos
use Mojo::Base 'MojoX::Model';

... code of your module ...

sub your_method {
  my $self = shift;
  $self->app->get_base_rest_url(...);
}

1;
Run Code Online (Sandbox Code Playgroud)

并且在您的App.pm中需要添加以下内容:

$app->plugin('Model', {namespaces => ['Site::Model']});
Run Code Online (Sandbox Code Playgroud)

并在控制器中使用它:

$c->model('photos');
$c->app->model('photos');
Run Code Online (Sandbox Code Playgroud)