On 11/22/2010 09:17 AM, Martin Bendix wrote:
Hi,

As a Perl and Catalyst novice, I have recently completed the online Catalyst
tutorial, and read the Definitive Guide to Catalyst.  However, I have a few
questions about the basic structure of a thin controller, fat model application.

I'd like to take my learning to the next stage by writing a fully functioning
application, and the classic CD database seems like a good place to start - it
will at least be of use to me when it's done.

Given the following basic criteria, I would be grateful for some high-level
advice on how best to organise the application:

* I will be using DBIx::Class to access the database.
* At first, the initial user interface will be web based.
* I'd like to structure the application so that I can add additional interfaces
with relative ease in future (e.g., command line, web services, etc.).
* I'd like to create test scripts for as many of the modules/application
functions as possible.
* The application will provide the ability to create, search, update and delete
artists, tracks, and CDs.

I think that my understanding of the following is correct, but I would
appreciate any advice or pointers:

My model should be well separated from the controller.  Most, if not all of the
application functionality should be exposed via the model, so that the Catalyst
controller only needs to make simple calls to the model.  To do this, model
classes should be created in 'lib/myapp', with simple adapters in
'lib/myapp/Model', using Catalyst::Model::Adaptor.

At this point, I am a little less clear on how best to structure my application.

As my models will be primarily concerned with accessing the database, how much
database code should go in my model classes, and how much in the
DBIx::Class::ResultSet classes?  For example, should I write a method in my
DBIx::Class::ResultSet classes that can add new CDs when supplied with title,
artist and a track list?  Or would it be better to put this in my model?

Data validation could be handled by HTML::FormHandler, but any validation
performed here won't be of much use if I later provide an alternative interface
to my application.  I assume that I should therefore delegate validation to my
model as well, so that the same validation methods can be used no matter what
the interface?

Are there any good tutorials out there that cover this sort of thing?  At the
moment, I'm more interested in best practices for structuring a Catalyst
application than in the details of the code itself.  Are there any good open
source Catalyst applications that I can look at to help me with this?  I've had
a look at MojoMojo, but it's a little too complicated for me at the moment.


Many thanks,

Martin




_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/

I use DBIx::Class with multiple interfaces in the same app; this is the structure I've found most useful so far:

   ### the lib dir.
   lib/

   ### MyApp stores everything relevant to my app
   lib/MyApp

   ### "MyApp::Web" stores the web interface
   lib/MyApp/Web
   lib/MyApp/Web/Model
   lib/MyApp/Web/View
   lib/MyApp/Web/Controller

   ### HTML::FormHandler forms that are web-specific.
   lib/MyApp/Web/Form

   ### Stores db stuff for DBIx::Class.
   lib/MyApp/Schema/

   ### Normal DBIx::Class schema, results, and resultsets
   lib/MyApp/Schema/MyApp
   lib/MyApp/Schema/MyApp/Result
   lib/MyApp/Schema/MyApp/ResultSet

   ### Schema/Result and Schema/ResultSet contain things like Moose roles
   ### that I want to apply to multiple models, but that really only make
   ### sense in the context of this application.
   lib/MyApp/Schema/Result
   lib/MyApp/Schema/ResultSet

   ### A namespace for script based access to the app
   lib/MyApp/Script
   lib/MyApp/Script/User
   lib/MyApp/Script/User/Create.pm
   lib/MyApp/Script/Report
   lib/MyApp/Script/Report/Documentation.pm

   ### Libs specific to the CLI
   lib/MyApp/CLI

   ### Tests
   t

   ### Store
   t/lib

A couple of notes:

The contents of lib/MyApp/Script are scripts that use MooseX::GetOpt. I added a helper script in script/myapp_utils.pl that allows me to do this (this is mock output, but you get the idea). In the example below, it scans through the following namespaces in order: MyApp::Script, $ENV{MYAPP_SCRIPT_NAMESPACE}, CatalystX::Script, Catalyst::Script; looking for ::Schema::Loader.

   ### Run with no arguments
   $ ./script/myapp_utils.pl
   Available scripts:

      Report::Testing
      Report::Documentation
      Schema::Loader
      User::Create
      User::Modify
      ...

   $ ./script/myapp_utils.pl Schema::Loader
   An error has occurred: Required option missing: username
   usage: myapp_utils.pl [-?bdnpu] [long options...]
        -? --usage --help          Prints this usage information.
        -u --usr --user --username  A username with which to log into
   the db
        -p --pwd --pass --password  A password with which to log into
   the db
        -b --db --dsn              The DSN of the source database (e.g.
   "dbi:mysql:myapp")
        -d --dir --directory       a directory into which to install
   the schema
        -n --namespace             the path to a directory

   $ ./script/myapp_utils.pl Schema::Loader \
   --user      ogopogo                      \
   --pass      vonmugwumpus                 \
   --dsn       dbi:mysql:my_db              \
   --dir       lib                          \
   --namespace MyApp::Schema::MyApp

   Creating schema ... done.

   $

Web forms are stored in the path like Halifax::Web::Form::CD::Create (create a new CD from the script interface).

FWIW =)

-Sir











_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/

Reply via email to