views:

885

answers:

4

Given a DBIx::Class resultset, for example:

my $rs = $c->model("DB::Card")->search({family_name => "Smith"});

the tutorials I've read use the stash to pass an arrayref of rows:

$c->stash->{cards} = [$rs->all];

This results in the query getting executed at this point, and the resulting objects stuffed into the stash, so they can be used in TemplateToolkit as:

[% FOREACH card IN cards %] 
    [% card.given_name %] [% card.family_name %] 
[%END%]

Is there a proper way to have TT iterate over the rows as they get fetched from the DB?

+7  A: 

Sure. You can pass the result set directly to TT and iterate over it in the template.

$c->stash->{cards} = $rs;

...and then:

[% WHILE (card = cards.next) %]
    [% card.given_name %] [% card.family_name %]
[% END %]
friedo
+2  A: 

Or, even better:

$c->stash(cards => $rs);

...in TT template:

[% FOREACH card = cards %]
    [% card.given_name %] [% card.family_name %]
[% END %]
delta
Does this work? - FOREACH takes an array, not a recordset, no?
Thelema
+1  A: 

I do:

@{$c->stash->{cards}} = $rs->all;

In the template:

[% FOREACH card IN cards %]
    [% card.given_name %] [% card.family_name %]
[% END %]
Julien
memory hungry with a large resultset.
singingfish
Yes, this is given as example code, but isn't very efficient
Thelema
+1  A: 

I WAS doing exactly the same thing as the author.

In trying to create a more strict MVC approach, I'm now processing the DBIC objects in the controller and passing a very simple stash for the template to display. (Key benefit being the code is reusable by other scripts instead of just the web interface.)

I'm curious if anyone knows if this is more efficient or not, processing or memory-wise. I would think the first method results in less processing time but holds onto memory longer. I'd guess my new approach takes a bit more processing and a bit more memory temporarily, but the potentially large result set object doesn't live as long.

Chris