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

Joshua Miller unrtst at gmail.com
Wed Sep 24 11:18:28 EDT 2008


On Wed, Sep 24, 2008 at 9:04 AM, Richard Jones <ra.jones at dpw.clara.co.uk>wrote:

> 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?


Oops, change this:
my $subclass = shift or die 'Required attribute missing';
my $obj = WebApp::DB::$subclass->new();

To this:
my $classname = shift or die 'Required attribute missing';
my $subclass = "WebApp::DB::$classname";
my $obj = $subclass->new();


More information about the cgiapp mailing list