[Catalyst] Is C::M::CDBI::Plain deprecated?

Brian Kirkbride brian.kirkbride at deeperbydesign.com
Thu Mar 2 18:51:44 CET 2006


Hello all,

I've been watching this project for a long time and have been amazed at the speed and quality of the development.  Many thanks to the people devoting their time to such a great framework.

I am in the process of porting an app to Catalyst from a simple framework of my own.  I have a number of existing Class::DBI models that I want to reuse and it looked like C::M::CDBI::Plain was the way to do that:

           # FROM THE POD
           # use existing CDBI classes within Catalyst:
           package MyApp::Model::Artist; # a Catalyst class
           use base qw[Catalyst::Model::CDBI::Plain Some::Other::Artist];
           1; # That's it--Some::Other::Artist is in Catalyst as MyApp::Model::Artist

This however, did not work for me at all.  Mysterious behavior like updates not happening, has_a not working, etc.  After pulling out my hair and examining/disabling the CDBI object index I found the cause of the problem.  It actually has to do with the multiple inheritance and Class::Data::Inheritable I believe.

If C::M::CDBI::Plain is in @ISA before Some::Other::Artist, class data from the existing class (like __grouper) is not seen.  This is because MyApp::Model::Artist->__grouper will be the inherited (and useless) Class::DBI->__grouper.  So I switched to:

           use base qw[Some::Other::Artist Catalyst::Model::CDBI::Plain];

Now a test of MyApp::Model::Artist->__grouper does indeed return Some::Other::Artist->__grouper as desired.  But, of course, this is not going to work inside of Catalyst because MyApp::Model::Artist->new() will be the inherited and deprecated Class::DBI->new() instead of the C::M::CDBI::Plain->new() that calls Catalyst::Base->new().

My 5am, coffee-list solution was the rather inelegant:

           package MyApp::Model::Artist;
           use base qw/ Some::Other::Artist /;
           use MyApp::MakeModel;
           1;

           package MyApp::MakeModel;
           use Exporter 'import';
           our @EXPORT = qw/ new /;
           sub new {
               my $class = shift;
               $class->Catalyst::Model::new(@_);
           }
           sub import {
               require Catalyst::Model;
               my $model_class = caller(0);
               push @{"$model_class\::ISA"}, 'Catalyst::Model';
               goto &Exporter::import;
           }
           1;

This works perfectly so far, but is hideous and the inheritance introduced is not obvious when looking at MyApp::Model::Artist.  Ideally I'd just place MakeModel after the existing model in the "use base" clause.  But I don't know a way to get a "use base"'d class to export a method off the top of my head.

So the questions at the end of all of it are:

Is anyone using C::M::CDBI::Plain?
If not is it deprecated or not-working?  
Is there an easier/better way to do this?
  
I've seen discussion questioning the usefulness of making your models Cat components, but I want to for cleanliness and to do $c->model('Artist').  I have started experimenting with a Modelize plugin that takes a list of classes and turns them into models the same way that MyApp::MakeModel does above.  Would that be a (somewhat) cleaner solution?


Thanks again for such a lively development effort, it's been fun following it.

- Brian Kirkbride



More information about the Catalyst mailing list