相关文章推荐
打酱油的柿子  ·  Perl 数组 | 菜鸟教程·  2 天前    · 
酷酷的红金鱼  ·  Spring ...·  1 年前    · 
帅呆的茴香  ·  PyQ5 - 知乎·  1 年前    · 
悲伤的山羊  ·  pymysql.err.Operationa ...·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have an existing application (my website) that I'm doing some code tidying in, and the tidy up is following the same sort of idea as the Mojo::Pg example here , with separate model and controller files to keep things defined. My site accesses both Flickr and Last.fm's APIs, and I have a helper defined in 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;

The problem I'm running into is that I don't know how to access that helper from the Site::Model::Photos module. The error is

Can't locate object method "get_base_rest_url" via package "Site::Model::Photos"

which is fair enough, but I can't work out how to actually get at that get_base_rest_url helper (or alternatively, how to access the api_token config).

Use the URI module (and possibly URI::QueryParam) for building elaborate URLs. Also, you shouldn't put simple scalar variables inside quotes, as in "$base_url", Just $base_url is correct. I'm sorry that this has nothing to do with your stated problem, but I hoped you would appreciate the advice – Borodin Mar 29, 2015 at 9:02

The problem is that your module have not got app attribute/method which get access to your app.

So, when you create instance of Site::Model::Photos you need to pass app to it in param and make it weaken something like that:

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(...);

Or you may to use this module https://metacpan.org/release/Mojolicious-Plugin-Model which do it for you:

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(...);

And in your App.pm need to add this:

$app->plugin('Model', {namespaces => ['Site::Model']});

And use it that in controller:

$c->model('photos');
$c->app->model('photos');
                The first suggestion just gave me a "Can't weaken a nonreference" error, but the second worked. Thanks!
– VirtualWolf
                Mar 31, 2015 at 10:27
                First example should work. I have a proof of that: gist.github.com/Logioniz/ce2b53c9647cf0204e81  To run: perl 1.pl get /  The result must be "zxc"
– Logioniz
                Mar 31, 2015 at 12:55
                I also use the second variant with Mojolicious-Plugin-Model! Because very frequently need to pass $app to modules.
– Logioniz
                Mar 31, 2015 at 12:58
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.