[Catalyst] Sharing a database handle between components

Aristotle Pagaltzis pagaltzis at gmx.de
Sat Feb 9 17:39:27 GMT 2008


Hi all,

I have the following situation: in our app, some templates need
to be user-customisable (we do some white-labelling basically),
so those come from the database. For that, I wire up my view,
which is TT, with Template::Provider::DBI. But I want T::P::DBI
to share the same handle used by my model (an app-specific
abstraction over the database).

My first problem was that I had no way to get at the app instance
from within MyApp::View::TT::new, much less from within the
`__PACKAGE__->config` call at load time. The only way I could
think of at first was to have `ACCEPT_CONTEXT` check whether
TT’s `LOAD_TEMPLATES` contained a T::P::DBI instance, and if
not, stick one in there. But that’s just a hack; the T::P::DBI
instance needs to be created only once, but this code checks for
its presence on every request, not to mention it would *create*
a new instance for every request when running under a forking
engine and might even break completely under a threading one.

After a pointer I got from jshirley on IRC I noticed that the
boilerplate generated by the default helper includes a
`__PACKAGE__->setup` call at the bottom of MyApp.pm. I felt a
bit sheepish.

For some reason, the next thing I tried,

    sub setup {
        my $class = shift;
        $class->NEXT::setup( @_ );
    }

didn’t work.

But never mind that – since I’m calling `__PACKAGE__->setup`,
I know what’s going to happen so I can just add some code below
that line.

So now I have a `add_dbi_provider` method in MyApp::View::TT, and
then in MyApp.pm I do

    __PACKAGE__->setup;
    __PACKAGE__->view('TT')->add_dbi_provider( __PACKAGE__->model('MyApp')->dbh );

This seems hackish too, but at least it’s far better, I think,
than the hack I had before.

Questions: is this remotely sane? Is there a better way to go
about all this? Is there a way that will work now *and* after
the app/context switch jshirley mentioned?

-- 
*AUTOLOAD=*_;sub _{s/(.*)::(.*)/print$2,(",$\/"," ")[defined wantarray]/e;$1}
&Just->another->Perl->hack;
#Aristotle Pagaltzis // <http://plasmasturm.org/>



More information about the Catalyst mailing list