[Catalyst] Instant CRUD with DBIC::Schema

Peter Karman peter at peknet.com
Wed Mar 12 14:25:17 GMT 2008



On 03/12/2008 07:11 AM, Zbigniew Lukasiak wrote:

>>  I think it would be best  to be able to treat a CatalystX::CRUD
>>  application like any other catalyst application.  That is, minimal
>>  modification of $c->model('Foo') compared to an ordinary catalyst app
>>  so that the CRUD generator mostly gets out of the way.
>>
> 
> Just thinking how this can be done - you need a
> CatalystX::CRUD::ModelAdaptor::XXXX and a model_adaptor_class config
> option for the CRUD controller.  Then in the controller methods you
> would do:
> 
> $c->stash->{object} = $self->model_adaptor->fetch( @arg );
> 
> instead of
> 
> $c->stash->{object} = $c->model( $self->model_name )->fetch(@arg);
> 
> and in places where you call methods on the object like: $obj->$method
> you could do again $self->model_adaptor->$method( $obj ).
> 
> This way $c->stash->{object} could still be an unmodified object from
> the model and you would have your indirection layer needed to make the
> CRUD methods universal.

That seems to exchange one relative complexity for a different relative complexity. Not
sure how it makes it simpler.

Maybe this will help: I use my CX::CRUD::Model::Foo models in controllers other than my
CRUD controller. I assume CRUD isn't the *only* thing folks do in their apps. So I want to
be able to interact directly with the Foo model in any controller. If I must then
implement an extra model adapter in those other, non-CRUD controllers, I have added extra
complexity where before there was none.

Example:

 package MyApp::Controller::Foo;

 sub thing : Local {
     my ($self, $c, $id) = @_;
     my $thing = $c->model('Foo')->fetch( id => $id );
     $c->stash->{object} = $thing;
 }

nice and simple. $thing might be a CatalystX::CRUD::Object, but it should behave just like
whatever its delegate() is, thanks to the evil AUTOLOAD stuff. So from the perspective of
MyApp::Controller::Foo and whatever View ends up presenting 'object' in stash(), $thing is
a $thing.

What I hear you suggesting is that a ModelAdaptor would mean I'd have to do:

 sub model_adaptor {
    my ($self) = @_;
    return $self->{_model_adaptor}; # instance of CatalystX::CRUD::ModelAdaptor::Foo
 }

 sub thing : Local {
    my ($self, $c, $id) = @_;
    my $thing = $self->model_adaptor->fetch( id => $id );
    $c->stash->{object} = $thing;  # NOT a CatalystX::CRUD::Object
 }

I guess it removes the delegate() and AUTOLOAD stuff. That would be simpler. But maybe we
could simplify it even further.

Your ModelAdaptor is essentially what a CX::CRUD::Model is already. If we moved the
create/read/update/delete methods to CX::CRUD::Model we could make CX::CRUD::Object
superfluous. (I suggested this in an earlier email.)

So we'd have:

 sub thing : Local {
     my ($self, $c, $id) = @_;
     my $thing = $c->model('Foo')->fetch( id => $id );
     $c->stash->{object} = $thing;  # NOT a CX::CRUD::Object
 }

and if wanted to update $thing:

     $c->model('Foo')->update( $thing );

I could live with that. Does it meet your needs? Does it make it easier to implement a
DBIC model and FormFu controller?

-- 
Peter Karman  .  peter at peknet.com  .  http://peknet.com/




More information about the Catalyst mailing list