Hi Jason, I don’t want to provide neither app or controller nor db. All your examples have to pass db which is not a good practice I think. But if I need to provide app->db and app->config and app->cache and something else from app then easier to provide just app and find everything else in it.
Cheers Eugene > On Apr 20, 2015, at 2:39 PM, Jason Galea <[email protected]> wrote: > > 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 <http://lecstor.com/> > ezyapp.com <http://ezyapp.com/> > On Mon, Apr 20, 2015 at 8:27 PM, Eugene Toropov <[email protected] > <mailto:[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] >> <mailto:[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] >>> <mailto:[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] >>>> <mailto:[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 >>>> <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] >>>> <mailto:[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 >>>>> >>>>> <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] >>>>> <mailto:[email protected]>. >>>>> To post to this group, send email to [email protected] >>>>> <mailto:[email protected]>. >>>>> Visit this group at http://groups.google.com/group/mojolicious >>>>> <http://groups.google.com/group/mojolicious>. >>>>> For more options, visit https://groups.google.com/d/optout >>>>> <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] >>>> <mailto:[email protected]>. >>>> To post to this group, send email to [email protected] >>>> <mailto:[email protected]>. >>>> Visit this group at http://groups.google.com/group/mojolicious >>>> <http://groups.google.com/group/mojolicious>. >>>> For more options, visit https://groups.google.com/d/optout >>>> <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] >>> <mailto:[email protected]>. >>> To post to this group, send email to [email protected] >>> <mailto:[email protected]>. >>> Visit this group at http://groups.google.com/group/mojolicious >>> <http://groups.google.com/group/mojolicious>. >>> For more options, visit https://groups.google.com/d/optout >>> <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] >> <mailto:[email protected]>. >> To post to this group, send email to [email protected] >> <mailto:[email protected]>. >> Visit this group at http://groups.google.com/group/mojolicious >> <http://groups.google.com/group/mojolicious>. >> For more options, visit https://groups.google.com/d/optout >> <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] > <mailto:[email protected]>. > To post to this group, send email to [email protected] > <mailto:[email protected]>. > Visit this group at http://groups.google.com/group/mojolicious > <http://groups.google.com/group/mojolicious>. > For more options, visit https://groups.google.com/d/optout > <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] > <mailto:[email protected]>. > To post to this group, send email to [email protected] > <mailto:[email protected]>. > Visit this group at http://groups.google.com/group/mojolicious > <http://groups.google.com/group/mojolicious>. > For more options, visit https://groups.google.com/d/optout > <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.
