[Catalyst] Begginer's question about application structure

Eden Cardim edencardim at gmail.com
Tue Nov 23 00:59:18 GMT 2010

>>>>> "Martin" == Martin Bendix <martinbendix at yahoo.co.uk> writes:

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

Controllers need to act as an adaptor between the model and the
view. So, for instance, mapping $cd->artist into a value that's suitable
for placing in a form field "value" attribute is the responsibility of
the controller (cos' when you change the UI into a CLI switchboard, for
instance, the mapping is going to be different).

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

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

You need to constrict the scope of your methods as much as
possible. That is, try not to write any code that makes the ResultSet
aware that it's being used in a web application. I find that most of
DBIC's API is well suited for being invoked directly by the
controller. You just need to avoid any constructs that make the
controller aware that there's actually a relational database behind the
model, because then you're free to swap out to an alternative
implementation. A general rule of thumb is to try to avoid writing
complex ->search methods in the controller, put those behind a
friendlier method on the ResultSet, for instance write a resultset
method that allows you to write $cds->released('this year') (which you
can implement via DatetimeX::Easy) instead of
$cds->search({ 'YEAR(me.date)' => DateTime->now->year }).

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

I'm of the opinion that using form generators puts you through the same
amount of trouble than writing/validating forms by hand, so I just dodge
the HTML::FormHandler thing altogether, but that's just me, YMMV.

     Eden Cardim            Need help with your perl Catalyst or DBIx::Class project?
   Software Engineer                   http://www.shadowcat.co.uk/catalyst/
 Shadowcat Systems Ltd.        Want a managed development or deployment platform?
http://blog.edencardim.com             http://www.shadowcat.co.uk/servers/

More information about the Catalyst mailing list