[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