[Dbix-class] Issues getting Catalyst::Model::DBIC::Schema to layer lib/MyApp/Model/Foo.pm on top of generated version

Brandon Black blblack at gmail.com
Sun Feb 26 00:23:28 CET 2006


On 2/25/06, Scotty Allen <lists at scottyallen.com> wrote:
> So, I'm gradually trying to migrate from CDBI to DBIC for a Catalyst
> project.  I'd like to use Catalyst::Model::DBIC::Schema in a similar
> fashion to how I've been using Catalyst::Model::CDBI.  Specifically, I'd
> like the loader to be in charge of loading the columns and such, and yet
> also be able to tweak relationships and add additional methods via a
> class in lib/Model.
>
> I noticed that the changelog for 0.07 of C::M::DBIC::Schema says:
>
>         - Added ->require for source classes, so that you can
>           layer in lib/MyApp/Model/Foo/Bar.pm on top of the
>           generated MyApp::Model::Foo::Bar.
>
> However, either this is borked, or it just doesn't work like I expect it
> to.
>

It's just borked.  It was added in as a last minute thing in the hopes
that a simple ->require was good enough to give at least some
functionality to someone.  Clearly that's not the case.

But in any case, here's a few other things on this subject in general:

1) If you're using DBIx::Class::Schema::Loader (or the Helper which in
turn uses it, C::H::M::DBIC::SchemaLoader), you can layer effectively
back at the Schema rather than the Model layer. 
DBIx::Class::Schema::Loader's layering actually works, whereas the one
at the Model level is obviously borked.  The reason we need to support
it at both levels is that sometimes you want to override things in the
Schema itself (for all code that uses your Schema), and sometimes you
want to override stuff just in the Catalyst Model (to do
Catalyst-specific things that perhaps other non-Catalyst Schema-using
code might not want to see).  The different is entirely acedemic if
the Schema is local to your Cat app only.

What the Model level really needs is all of the exact same layering
support that the Schema level currently has, but it's slightly
trickier to actually get that done at the Model end, more magic
involved.  The %INC problem is because Catalyst itself already loaded
your model class I believe, which I guess means it ignored the "die
foo" (which sounds pretty normal).  Given that Catalyst will load your
layered file at some point anyways, the ->require I stuffed in there
was probably completely superfluous, and at the same time, still kinda
broken :)

2) Even after you hacked the ->require part to work (or if you using
Schema rather than Model layering as above), a subroutine in the
layered class definition will not show up as
$c->model('Foo::Bar')->foo();.  $c->model('Foo::Bar') is a ResultSet,
and subroutines placed in that file do not end up in the default
ResultSet for your source, rather they end up in the source class
definition.  This is a DBIx::Class::Schema thing in general, see the
Schema/ResultSet/ResultSource/etc docs. 
$c->model('Foo::Bar')->result_source->foo() may have worked.

You can get new functions into the ResultSet part, but it's a little
trickier.  There's some support for doing it automagically via a
component called DBIx::Class::ResultSetManager that lets you define
"sub foo : ResultSet { }" in that same .pm file, and the sub will show
up in the ResultSet.  However, I think this interface is brand new and
possibly subject to change sometime soon.

-- Brandon



More information about the Dbix-class mailing list