[Catalyst] Dynamic model and controller creation
Tomas Doran
bobtfish at bobtfish.net
Mon Jan 2 11:42:59 GMT 2012
On 1 Jan 2012, at 04:58, Bill Moseley wrote:
> Then I have Controller classes inheriting from this class that are
> simply config setting the "model_class" attribute:
>
> package MyApp::Controller::Service::Bolt;
> use base 'MyApp::ControllerBase::Inventory;
> __PACKAGE__->config( model_class => 'Inventory::Bolt',);
> 1;
>
> Which means the base class just does $c->model( $self->model_class )
> to get at the Inventory::Bolt model.
>
> Then, likewise, I have a Model base class that uses ACCEPT_CONTEXT
> to return specific instances:
>
> package MyApp::ModelBase::Inventory;
> use Moose;
> use namespace::autoclean;
> extends 'Catalyst::Model';
>
> has service => ( is => 'rw' ); # instance of model
>
> has service_class => (
> is => 'ro',
> isa => 'Str',
> required => 1,
> );
>
>
> # wrapping "setup_components" might be another approach
> sub ACCEPT_CONTEXT {
> my ( $self, $c, @args ) = @_;
>
> my $service = $self->service;
>
> unless ( $service ) {
> my $service_class = $self->service_class;
> Class::MOP::load_class( $service_class );
>
> $service = $service_class->new;
>
> # Save our instance
> $self->service( $service );
> }
>
> return $service;
> }
>
>
> __PACKAGE__->meta->make_immutable;
> 1;
>
> And then the specific model classes are simply:
>
> package MyApp::Model::Inventory::Bolt;
> use base 'MyApp::ModelBase::Inventory';
> __PACKAGE__->config( service_class => 'Inventory::Service::Bolt' );
> 1;
>
> Of course, after doing that a few times I'd rather use a programatic
> solution.
>
Why are you messing around with ACCEPT_CONTEXT to do this?
Why not just use COMPONENT to return the service class once?
I.E., what does your current solution do which using
Catalyst::Model::Adaptor doesn't do (and that does the initialisation
of the service classes as startup, rather than at first request -
which is nicer for catching issues, and memory usage).
> So, what I'd like is to remove the need to create those stub
> Controller and Model classes and instead use config (or maybe
> detection of available subclasses at startup).
Have a look at this:
https://github.com/bobtfish/CatalystX-JobServer/blob/master/lib/CatalystX/JobServer/Web/Plugin/ModelsFromConfig.pm
#L7
Which is code to do exactly what you want - i.e. setup any models
there is config for, but which don't have an explicit class on-disk,
and then go on to setup controllers for each model setup.
Cheers
t0m
More information about the Catalyst
mailing list