[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