The best example to consider here is testing. When you write your tests
for MyApp::Model::Users do you want to have to have $c as it exists in
Mojolicious (or a complex mock of it) or would you prefer to just have to
give it what it needs to work?

$app = Mock::App->new(db => $db, config => Mock::Config->new({}));
my $users = MyApp::Model::Users->new(app => $app);

..blah blah..

or rather

$users = MyApp::Model::Users( db => $db, partner_id => 4321, other_config
=> 'options' );

If you have more models, then you do something like..

$model = MyApp::Model->new(db => $db, other_config => 'options');
$users = $model->users( partner_id => 4321 );

or

$model = MyApp::Model->new(db => $db,  partner_id => 4321, other_config =>
'options' );
$users = $model->users();

The main point though is to keep your package separate from Mojolicious (or
any other module/framework) to keep it simple, testable, and portable.




Jason Galea
lecstor.com
ezyapp.com

On Mon, Apr 20, 2015 at 8:27 PM, Eugene Toropov <[email protected]>
wrote:

> Hi Jan,
>
> My case is as follows: we have a number of partners application must
> communicate with. Every partner is basically a separate package with a
> number of common methods (download, import, search, book, etc). Right now
> I’m implementing download method (to run via "app partner download
> <partner_id>" command) for a number of partners. It basically gets data
> from partner (FTP or SOAP or other kind of XML/JSON/custom format web
> service) and saves in database so it needs app->db handler and a number of
> config parameters from app->config.
>
> Your example is about something different. You don’t tell model where and
> how it must search data you want. You simply provide input parameter (but
> not app->db) and obviously 2nd option doesn’t make sense.
>
> Cheers
> Eugene
>
> On Apr 20, 2015, at 12:50 PM, Jan Henning Thorsen <[email protected]>
> wrote:
>
> "Many people" != "Mojolicious people". This is a very generic problem,
> where a higher level object pass itself to a lower level object. What I
> mean is that you build stuff from small components built on top of each
> other, and then you have this high level object on top which "orchestrate"
> the objects, passing on just enough information to make each of them work.
>
> I will try to come up with a new example. Which of these two lines of code
> makes most sense to you?
>
>   $user = $c->model->users->find({id => $c->param("user_id")});
>   $user = $c->model->users->find($c);
>
>
> Btw... I'm drifting. Your original question is very specific and not
> explaining why you want to pass $app to the model. Can you try to explain
> why you need to pass on $app to the model? Do you have an example
> usecase/piece of code where that makes most sense?
>
>
> On Monday, April 20, 2015 at 11:10:20 AM UTC+2, Eugene Toropov wrote:
>>
>> Right, well, I hope Sebastian will have a moment to reply at some point
>> if it comes up so often and so many people were "in the same state of mind"
>> :) Or he did already? If so - would be great if someone could provide a
>> link. Thank you.
>>
>> Cheers
>> Eugene
>>
>> On Apr 20, 2015, at 11:49 AM, Jan Henning Thorsen <[email protected]>
>> wrote:
>>
>> It's so funny how this questions comes up over and over again. I even
>> have to battle it myself from time to time, even when I know how stupid
>> (Sorry for using "stupid", but I think I'm allowed as it reflects back on
>> myself), limiting, hard to get around later, ... it would be to pass some
>> $app-like object around to lower level models.
>>
>> Also, I probably know how your mind is set on your statement, and how you
>> probably just want to get confirmation instead of the answer I'm giving
>> you. Yes... Me and many before you have been in the same state of mind.
>>
>> So... I was hoping I could help you with my Mojo::Pg->new() example
>> above, but it seems like I have failed.
>>
>> I wish you the best of luck finding the right solution.
>>
>> I also apologize if I'm stepping on yours or anyone else's toes. That is
>> not my intention.
>>
>>
>> On Monday, April 20, 2015 at 10:31:45 AM UTC+2, Eugene Toropov wrote:
>>>
>>> Hi Jan,
>>>
>>> Having to pass "db => shift->model->db” in every model helper doesn’t
>>> seem like invisible way ;) It would be really invisible if you had “use DB”
>>> inside a model package and then “my $db = $DB::dbh” :) but then you’d have
>>> to somehow pass app->config to DB. Also if you kept something in
>>> app->config that model needs - would you pass it as another parameter to
>>> every model you had? What if then you had app->cache (redis/memcached) ?
>>> Another parameter to pass to every model again? I feel it doesn’t seem good
>>> but can’t find any other way in Mojo to do it so thought someone had found
>>> the solution...
>>>
>>> Cheers
>>> Eugene
>>>
>>> On Apr 20, 2015, at 11:18 AM, Jan Henning Thorsen <
>>> [email protected]> wrote:
>>>
>>> I pass on $db to every instance of a model in MCT:
>>> https://github.com/mojoconf/MCT/blob/master/lib/MCT.pm#L33
>>>
>>> Just make a helper where the passing of $db (or any other common
>>> argument) is "invisible".
>>>
>>> The nice thing is that the model will need to know less. It will then be
>>> easier to use for "other things" outside of your Mojo app. To flip the
>>> question around. Which version ofof the code below makes most sense?
>>>
>>>   my $app = Mojolicious->new;
>>>   $db = Mojo::Pg->new(app => $app);
>>>   $db = Mojo::Pg->new(app => $app->config->{db}{dsn});
>>>
>>> (I hope the version where $app is passed to new() looks weird...)
>>>
>>>
>>> On Monday, April 20, 2015 at 9:17:27 AM UTC+2, Eugene Toropov wrote:
>>>>
>>>> Hi Jan,
>>>>
>>>> Thanks for your reply. Don’t you think that passing app->db to every
>>>> model is not a good idea neither because model must know itself where data
>>>> are and how to fetch it and pass to controller? Also it’s simply
>>>> inconvenient to always have one (or even 2 - app->db and app->redis for
>>>> example) arguments passed to every model, no?
>>>>
>>>> Cheers
>>>> Eugene
>>>>
>>>> On 20 Apr 2015, at 10:07, Jan Henning Thorsen <[email protected]>
>>>> wrote:
>>>>
>>>> You don't. Passing $app or $c to a model is not a good idea. Reason for
>>>> this is that it makes it hard to reuse the models elsewhere. What you can
>>>> do, is passing data from $app when you construct your models, but I would
>>>> strongly advice against passing $app.
>>>>
>>>>
>>>> On Friday, April 17, 2015 at 4:38:06 PM UTC+2, Eugene Toropov wrote:
>>>>>
>>>>> Greetings,
>>>>>
>>>>> In the following example how will you make MyApp::Model::Users have
>>>>> access to app object (which is basically $self) that is necessary to use
>>>>> app->db and app->config?
>>>>>
>>>>>
>>>>> http://mojolicio.us/perldoc/Mojolicious/Guides/Growing#WELL-STRUCTURED-APPLICATION
>>>>>
>>>>> package MyApp;use Mojo::Base 'Mojolicious';
>>>>> use MyApp::Model::Users;
>>>>> sub startup {
>>>>>   my $self = shift;
>>>>>
>>>>>   $self->secrets(['Mojolicious rocks']);
>>>>>   $self->helper(users => sub { state $users = MyApp::Model::Users->new });
>>>>>
>>>>>   my $r = $self->routes;
>>>>>
>>>>>   $r->any('/' => sub {
>>>>>     my $c = shift;
>>>>>
>>>>>     my $user = $c->param('user') || '';
>>>>>     my $pass = $c->param('pass') || '';
>>>>>     return $c->render unless $c->users->check($user, $pass);
>>>>>
>>>>>     $c->session(user => $user);
>>>>>     $c->flash(message => 'Thanks for logging in.');
>>>>>     $c->redirect_to('protected');
>>>>>   } => 'index');
>>>>>
>>>>>   my $logged_in = $r->under(sub {
>>>>>     my $c = shift;
>>>>>     return 1 if $c->session('user');
>>>>>     $c->redirect_to('index');
>>>>>     return undef;
>>>>>   });
>>>>>   $logged_in->get('/protected');
>>>>>
>>>>>   $r->get('/logout' => sub {
>>>>>     my $c = shift;
>>>>>     $c->session(expires => 1);
>>>>>     $c->redirect_to('index');
>>>>>   });}
>>>>> 1;
>>>>>
>>>>> Cheers
>>>>> Eugene
>>>>>
>>>>
>>>> --
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Mojolicious" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to [email protected].
>>>> To post to this group, send email to [email protected].
>>>> Visit this group at http://groups.google.com/group/mojolicious.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>>
>>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Mojolicious" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to [email protected].
>>> To post to this group, send email to [email protected].
>>> Visit this group at http://groups.google.com/group/mojolicious.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>>
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Mojolicious" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> To post to this group, send email to [email protected].
>> Visit this group at http://groups.google.com/group/mojolicious.
>> For more options, visit https://groups.google.com/d/optout.
>>
>>
>>
> --
> You received this message because you are subscribed to the Google Groups
> "Mojolicious" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/mojolicious.
> For more options, visit https://groups.google.com/d/optout.
>
>
>  --
> You received this message because you are subscribed to the Google Groups
> "Mojolicious" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/mojolicious.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Mojolicious" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/mojolicious.
For more options, visit https://groups.google.com/d/optout.

Reply via email to