FAQ
Hi all,

I need to create a Model class that returns an object that is mostly build during component initialization time, but also has access to the current request. The API will look like this:

sub my_action {
my ($self, $c) = @_;
my $formfu = $c->model('FormFu');
my $book_form = $formfu->form('book');
# do stuff with $book_form
}

The main $formfu object is built during app initialization time - it reads configuration files, builds a bunch of forms and does onther expensive tasks. When $c->model('FormFu') is invoked, I want to add to $formfu information about any query parameters from the current request before returning it, so that I can use it with the forms that are accessed afterwards. I tried something like the following:

package Catalyst::Model::FormFu;

use parent 'Catalyst::Model';

sub COMPONENT {
# get configuration options for this component,
# build and cache all forms,
# and put them into $self
}

sub ACCEPT_CONTEXT {
# get query parameters, add them to $self
# and return it
}

sub form {
# get the requsted form from the cache,
# add info about the current query and return it
}

However, if there is a 'COMPONENT' or 'new' sub, 'ACCEPT_CONTEXT' never gets called.

What is the right way to address this problem?

Cheers,

--
Peter

Search Discussions

  • Alejandro Imass at May 28, 2011 at 3:04 am

    On Fri, May 27, 2011 at 7:22 AM, Peter Shangov wrote:
    Hi all,

    I need to create a Model class that returns an object that is mostly build during component initialization time, but also has access to the current request. The API will look like this:
    So I'm not the only to have fallen into this trap ;-)

    Since you are deriving from catalyst model or component means you are
    creating an 'instance' type which in turn means that your model will
    be instanced once and left loaded as long as the app lives.

    COMPONENT will be called only once when Catalyst starts so you can
    merge the config and initialize your model internals.

    ACCEPT_CONTEXT will be called when you use $c->model([instance])->method();

    You should (must?) return a different model object that lives only for
    that particular request. In other words, your model instance is
    actually an object factory.

    The idea as I understand it, is for you to code your Business Models
    independent from Catalyst and call them per request with a thin
    wrapper (the per-instance object created by the instance/factory),
    that is, if you model actually needs the context, but will surely need
    some info from the request so the thin object is there precisely to
    translate that. Also remember Catalyst runs with multiple engines so
    you have to remember this when designing your models (beware of
    attributes in the instance class being changed by multiple requests
    (e.g. multi-threaded Perls).

    Best, and good luck finding any useful info on this topic "for the
    rest of us". I am trying to put together some for-dummies examples for
    this particular topic to publish on the wiki and/or POD, but sadly
    haven't had any free time for this.

    Also take a look at: Catalyst::Component::InstancePerContext
    It's supposed to ease the creating of per instance models, but I
    wonder. Hope you understand it ;-)

    --
    Alejandro Imass
  • Peter Shangov at May 28, 2011 at 1:24 pm
    Figured it out. The answer is?Catalyst::Component::InstancePerContext. The final code can be seen at?https://github.com/pshangov/catalyst-model-formfu/

    Cheers,

    --
    Peter

    ----- Original Message -----
    From: Alejandro Imass <alejandro.imass@gmail.com>
    To: The elegant MVC web framework <catalyst@lists.scsys.co.uk>
    Cc:
    Sent: Saturday, 28 May 2011, 6:04
    Subject: Re: [Catalyst] ACCEPT_CONTEXT not invoked if COMPONENT if present
    On Fri, May 27, 2011 at 7:22 AM, Peter Shangov wrote:
    Hi all,

    I need to create a Model class that returns an object that is mostly build
    during component initialization time, but also has access to the current
    request. The API will look like this:
    So I'm not the only to have fallen into this trap ;-)

    Since you are deriving from catalyst model or component means you are
    creating an 'instance' type which in turn means that your model will
    be instanced once and left loaded as long as the app lives.

    COMPONENT will be called only once when Catalyst starts so you can
    merge the config and initialize your model internals.

    ACCEPT_CONTEXT will be called when you use
    $c->model([instance])->method();

    You should (must?) return a different model object that lives only for
    that particular request. In other words, your model instance is
    actually an object factory.

    The idea as I understand it, is for you to code your Business Models
    independent from Catalyst and call them per request with a thin
    wrapper (the per-instance object created by the instance/factory),
    that is, if you model actually needs the context, but will surely need
    some info from the request so the thin object is there precisely to
    translate that.? Also remember Catalyst runs with multiple engines so
    you have to remember this when designing your models (beware of
    attributes in the instance class being changed by multiple requests
    (e.g. multi-threaded Perls).

    Best, and good luck finding any useful info on this topic "for the
    rest of us". I am trying to put together some for-dummies examples for
    this particular topic to publish on the wiki and/or POD, but sadly
    haven't had any free time for this.

    Also take a look at: Catalyst::Component::InstancePerContext
    It's supposed to ease the creating of per instance models, but I
    wonder. Hope you understand it ;-)

    --
    Alejandro Imass

    _______________________________________________
    List: Catalyst@lists.scsys.co.uk
    Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
    Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
    Dev site: http://dev.catalyst.perl.org/

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupcatalyst @
categoriescatalyst, perl
postedMay 27, '11 at 11:22a
activeMay 28, '11 at 1:24p
posts3
users2
websitecatalystframework.org
irc#catalyst

2 users in discussion

Peter Shangov: 2 posts Alejandro Imass: 1 post

People

Translate

site design / logo © 2021 Grokbase