This is another one in my series: I post this here in case I forget how I did it last time... :-)

I just had the following problem in my Catalyst app:
As a model I am using a class that has nothing to do with the Catalyst app itself. I want to instantiate objects of this class once per request, so I extend Catalyst::Model::Factory::PerRequest like this (my class needs its parameters to "new" in list form, not hashref):

package MyApp::Model::ProblemSolver; use Moose; use namespace::autoclean; extends 'Catalyst::Model::Factory::PerRequest'; __PACKAGE__->config( class => 'MyNonCatalyst::ProblemSolver', ); # provide arguments as a list instead of hash-ref sub mangle_arguments { my ($self, $args) = @_; return %$args; }

Now, objects of the MyNonCatalyst::ProblemSolver class need some parameters that go well in the app's config file, e.g. details for a database connection. It also needs parameters that will depend on input from the user of the site.
I found out that I can add this to the above model class (this is using the Moose way of overriding a parent's method and calling SUPER):

override 'prepare_arguments' => sub { my ($self, $c) = @_; my $config_params = super(); my $passed_in_params = $c->stash->{problem_solver_args}; my %merged_args = ( %$config_params, %$passed_in_params ); return \%merged_args; }; # prepare_arguments
This will merge the parameters from the config file and those that were passed in from the controller in such a way that the controller arguments override the config defaults. In my controller I can now do something like this:
$c->stash->{problem_solver_args}{some_param} = $user_input1 if $user_i +nput1; $c->stash->{problem_solver_args}{some_other_param} = $user_input2; my $problem_solver = $c->model('ProblemSolver'); my $result = $problem_solver->solve_problem();
in my my_app.yaml config file for the app I have:
Model::ProblemSolver: args: database: a_database_of_solved_problems some_param: SOME_DEFAULT_VALUE
This means that the database name is always taken from the app's config file but 'some_param' will be taken from user input if there is any or the above default is used to instantiate an object of the model class.

In reply to instantiate objects from non-Catalyst model classes with parameters by tospo

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.