[cgiapp] Re: Model design in C::A/Titanium

Richard Jones ra.jones at dpw.clara.co.uk
Wed Sep 24 09:04:46 EDT 2008


Joshua Miller wrote:
> On Tue, Sep 23, 2008 at 5:45 PM, Richard Jones <ra.jones at dpw.clara.co.uk>wrote:
>> Actually I quite like the idea of grouping associated db-related method
>> calls into WebApp::Model::Foo, WebApp::Model::Bar, etc, but not sure what is
>> the best way to get them into the call to $c->model, so I can call them as
>> $c->model('Foo')->get_stuff, $c->model('Bar')->update_stuff, etc. Pointers
>> appreciated.
>>
>>
> lots of options for that, but this should cover the basic concept:
> sub model {
>     my $c = shift;
>     my $subclass = shift or die "Required attribute missing";
> 
>     return $c->param("model::$subclass") if $c->param("model::$subclass");
> 
>     my $obj = new MyApp::DB::$subclass->new();
>     $c->param("model::$subclass", $obj);
>     return $obj;
> }
> (most of the code from my previous post could also fit in here to avoid
> infinite loops, and to automatically require the correct classes - tweak as
> needed).

OK, halfway there! At the moment I'm getting a fatal error:

[Dispatch] ERROR' for request '/': Unable to load module 
'WebApp::Controller::Foo': Bad name after :: at 
WebApp/Controller/Base.pm line 98.

############ WebApp::Controller::Base ###################
sub model {
   my $c = shift;
   my $subclass = shift or die 'Required attribute missing';
   ..
   my $obj = WebApp::DB::$subclass->new(); # <= THIS IS LINE 98
   $c->param("model::$subclass", $obj);
   return $obj;
}
###########################################################

But if I replace $subclass at lines 98 & 99 with a hardcoded variable eg 
'Foo', it works and I can pull data from the db in my controllers using 
$c->model('Foo')->get_stuff, as I wanted.

I'd guess the reason for this is that at first call (either after server 
startup if using Dispatch, or direct if using cgi), the Base controller 
methods are being parsed and there has not yet been a call to method(), 
so there is no $subclass passed, so 'WebApp::DB::$subclass->new' must 
fail. If this *is* the reason for the error, I'm not sure why the code 
in model() is executed before it's explicitly called in a controller.

I never see the 'Required attribute missing' warning, and if I put a 
'warn Dumper $subclass' statement after 'my $subclass = shift or die', 
it never outputs, which I think both go to confirming there is no 
$subclass being passed. Also tried "my $subclass = shift || 'Foo'", but 
that doesn't do it either.

I've not tried your sub AUTOLOAD method yet as it seemed a lot more 
complicated (ie I don't really understand it!), and the above method 
*seemed* simpler, but maybe there's something essential in sub AUTOLOAD 
I need to prevent the error I'm seeing?
--
Richard Jones


More information about the cgiapp mailing list