in reply to Re^2: Trying to understand Catalyst::Model::Adaptor
in thread Trying to understand Catalyst::Model::Adaptor

I think you're asking good questions and you know what you're doing because you already found and understand why Catalyst::Model::Factory::PerRequest exists. I do think I answered you pretty well, though. :) If it can be done simply, directly, and in one place, write it in the Controller class. If it is going to be used in several places, use the Model approach.

Part of the what the Model approach buys you is that the instantiation of objects can be done/extended/augmented through config. You can actually do this with Controllers too but I find it less graceful and it will again result in extra code if it's not in exactly one Controller.

If doing it in the Controller feels natural, go for it. It might be the fastest way to get going. Revisit if it starts to feel messy or like it's making extra work.

  • Comment on Re^3: Trying to understand Catalyst::Model::Adaptor

Replies are listed 'Best First'.
Re^4: Trying to understand Catalyst::Model::Adaptor
by tospo (Hermit) on Apr 07, 2010 at 08:14 UTC

    OK, thanks!

    In my case, I don't want to tie the instantiation of the model class too tightly to the Web App because I want to use it as a back-end for command line scripts as well. I guess that means I should use my first approach and simply require and use objects of the external model class directly in the controller without using any Model Adaptor.

      Oh, sure. There is a way to do that which buys you, in general, the best of both worlds.

      Something I do in most apps is keep parallel directories for agnostic parts of the application. The DB schema for example. I almost always use DBIx::Class. I put it parallel to the MVC parts. E.g.,

      MyApp::Controller MyApp::Model MyApp::View MyApp::Schema (or MyApp::DBIC or whatever) MyApp::SomeSpecialTextTransforms MyApp::ExternalWebservice

      Then only the MVC are directly tied to the web app and the other parts are generic modules which can be used without the app context ($c).

      I also generally keep a MyApp/bin for scripts I write that are not directly related to the web app and put scripts that are in the MyApp/scripts with the usual suspects.

      The extra classes are hooked into your web app through Model glue. Some are all but done for you, like Catalyst::Model::DBIC::Schema. Others you typically ride in on Catalyst::Model::Adaptor like we were discussing. This way the customizations you make to things are available to all your code in the most natural way and you only have to (in the best case) ever edit code in one place to get the changes to propagate everywhere you want. The single drawback to this is the Catalyst configuration system is too tightly bound to the application. There have been discussions about fixing this but no motion so far.

      Good luck and have fun!

      (update: spelling fixes.)

        Thanks. I agree to everything you say but I'm still not 100% sure about the benefits of Catalyst::Model::Adaptor. Let's assume a very simplistic scenario where I have the following model class that I want to use in my web app:

        package NonCatalyst::FileCat; sub new{ my ($class, $directory) = @_; bless { _directory = $directory }, $class; } sub cat{ my ($self, $file) = @_; my $cmd = 'cat '.$self->{_directory}.'/'.$file; return `$cmd`; } 1;
        So I instantiate with a directory and now I can get the contents of text files with the cat method on a file. Not very useful and realistic but it's just an example. Now I want my web app to display the contents of a file the user selects in a form. My instinct would be to do it like this in my controller:
        use NonCatalyst::FileCat; sub show :Local { my ( $self, $c ) = @_; my $fc = NonCatalyst::FileCat->new( $c->config->{file_directory}); my $file_name = $c->request->params->{file}; $c->stash->{result} = $fc->cat( $file_name ) ; }

        So I just use the external model class directly. If I need to make a change to FileCat I still only have one file to edit, so no difference to the Model::Adaptor approach there. All the configuration I need for FileCat is passd explicitly when creating the object, so I can use the same module from any script or UI implementation as long as it can pass a directory path. To me, that still seems a lot more natural and I would avoid the drawback you mention, i.e. tying my class too closely to the Catalyst configuration. Maybe this example is too simple but would you agree that this would be a case against using Catalyst::Model::Adaptor?