Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Catalyst DBIx Help

by PyrexKidd (Monk)
on Aug 12, 2011 at 07:03 UTC ( [id://919989]=perlquestion: print w/replies, xml ) Need Help??

PyrexKidd has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks.

I am working on a CRUD application using the Catalyst Framework and a Sqlite DB with a DBIx interface.

I have a controller with a list function like so:

sub list :Local { # Retrieve the usual Perl OO '$self' for this object. $c is the Ca +talyst # 'Context' that's used to 'glue together' the various components # that make up the application my ($self, $c) = @_; # Retrieve all of the book records as book model objects and store + in the # stash where they can be accessed by the TT template #$c->stash(resultset => [$c->model('DB::User')->all]); $c->stash (resultset => $c->model('DB::User')->all); use Data::Dumper; my $aref = $c->model('User'); $c->log->debug( Dumper $aref ); # Set the TT template to use. You will almost always want to do t +his # in your action methods (action methods respond to user input in # your controllers). $c->stash(template => 'main/list.tt'); }

Then I am using the following template:

[% cols = resultset.result_source.columns; FOREACH x IN cols; "<li>" +_ resultset.$x _ "</li>"; END %] [% # FOREACH row IN resultset %]Username: [% #row.username %]<br />[% +#END %] <table> <tr> <th>User Name</th> <th>Password</th> <th>Email</th> <th>FName</th> <th>LName</th> <th>Active</th> </tr> [% FOREACH row IN resultset %] <tr> <td>[% row.username %]</td> <td>[% row.password %]</td> <td>[% row.email_address %]</td> <td>[% row.first_name %]</td> <td>[% row.last_name %]</td> <td>[% row.active %]</td> </td> [% END %] </table>

the first line works, when I call:

$c->stash (resultset => $c->model('DB::User')->all);

but it only displays the first record. My table also only displays the first record in the table.

the first line doesn't work, and m y table displays all records when I call:

$c->stash (resultset => [$c->model('DB::User')->all]);

The problem is, what if I want to display the results of a different DB?
Seems that I should be able to use the same template... maybe I'm just not groking the model.

The tutorial says these are the same, the first two return undefined values:

# the long way my $rs = $c->model('FilmDB')->schema->resultset('Actor'); # using the shortcut method on the model object my $rs = $c->model('FilmDB')->resultset('Actor'); # using the generated class directly my $rs = $c->model('FilmDB::Actor');

Also, this returns a "can't find method" error:

my $dbic = $c->model('FilmDB')->schema; my $dbic = $c->model('DB::FilmDB')->schema;

I promise I have read the tutorials more than once.
I think the issue is probably something simple that I'm just misunderstanding.
Can someone please help me instead of just pointing me to the manuals?

Replies are listed 'Best First'.
Re: Catalyst DBIx Help
by Anonymous Monk on Aug 12, 2011 at 09:10 UTC

    Can someone please help me instead of just pointing me to the manuals?

    No such luck :)

    There are areas of improvement that I see, one being an effective node title :) How do I compose an effective node title?

    You probably had a tough time coming up with one, because your code is not self-contained, and you're asking more than one question , for improving on that :) see How do I post a question effectively?

    I imagine, an effective title might be "Creating generic DBIx... model template" or "DBIx... introspection" or ...

    The problem is, what if I want to display the results of a different DB? Seems that I should be able to use the same template... maybe I'm just not groking the model.

    From your template/description, I can deduce, that resultset is basically this data structure ( an AoH, array of hashrefs)

    [ { username => 'username1', password => 'password1', ...}, { username => 'username2', password => 'password2', ...}, ... ],
    So to make your template generic, you would use the Template equivalent of keys, which is keys so
    <table> [% IF hash = resultset.first %] <tr> [% FOREACH key IN hash.keys.sort %] <th>[% key %]</th> [% END %] </tr> [% END %] [% FOREACH hash IN resultset %] <tr> [% FOREACH key IN hash.keys.sort %] <td>[% hash.$key %]</td> [% END %] </tr> [% END %] </table>

    ->all probably returns different data structures in different context, see Tutorials: Context in Perl: Context tutorial, about context, and also see the related DBIx documentation :)

    For data structure info see perldata and the tuts it references, and same for Template :)

    There are other ways to a generic template, but I can't help you with that :)

Re: Catalyst DBIx Help
by Solo (Deacon) on Aug 25, 2011 at 08:40 UTC
    The problem is, what if I want to display the results of a different DB?

    With the caveat that I'm also new to Catalyst, this is what I used for generic DB access (for serving up JSON in my case).

    sub data : Chained CaptureArgs(2) { my ( $self, $c, $model, $object ) = @_; # ... $c->stash( model => $model, object => $object ); } sub list : PathPart Chained('data') { my ( $self, $c ) = @_; my $model = $c->stash->{model}; my $object = $c->stash->{object}; # ... $c->stash( json_data => [ $c->model($model)->resultset($object)->a +ll ] ); }

    --Solo

    --
    You said you wanted to be around when I made a mistake; well, this could be it, sweetheart.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://919989]
Approved by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (2)
As of 2024-04-20 04:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found