Friday, August 13, 2010

DBIx::Class join, prefetch

Over the last 15 years I've joined two database tables into a one-to-many relationship about a billion times. But I've never had any software let me loop the left table and right tables separately before. Turns out this magic has been in DBIx::Class for several years.

Runnable demo.

When table 'foo' is in a one-to-many relationship with table 'bar', you can:

my $foo_rs = $schema->resultset('Foo')->search(
{},
{
join => 'bars',
prefetch => 'bars',
order_by => 'me.id',
}
);

while (my $foo = $foo_rs->next) {
printf "%s\n", $foo->id;
if (my $bar_rs = $foo->bars) {
while (my $bar = $bar_rs->next) {
printf " %s\n", $bar->desc;
}
}
}
Output:

1
2
aaa
bbb
ccc
3
Still one SQL statement against the database (fast!). Much prettier than ugly manual de-duping of redundant columns.

2 comments:

mo said...

actually the join => "xxx" is optional

Htbaa said...

Yeah prefetch is magic. One of the things that makes DBIx::Class one of the best ORM's for me.