[Dbix-class] Prefetch Problem: Related data can't be fetched

Jess Robinson castaway at desert-island.me.uk
Wed Feb 27 12:57:00 GMT 2008


On Wed, 27 Feb 2008, sindharta_tanuwijaya at yahoo.co.jp wrote:

> Hi,
>
> My friend solved the problem. It's weird though and I am still a little bit confused. The way I am trying to access/display the rows is like this:
>
> [% FOREACH railway = railways -%]
>  [% railway.railway_station.railway_station_fields %]
> [% END -%]

Aha! You should have said so before..

Because this is a TT problem, not a DBIC problem.

If this is the latest TT, then "somethihng returning a list with one 
object, or multiple objects" is broken. Namely, the "returning one object" 
case doesn't work in any verson of TT > 2.15.

(It cleverly listifies the keys/values of the object, not the one 
object into a single item.

Basically, dont treat a list as one item, its not clever, in TT or 
anywhere else usually. If you make that another FOREACH it would be fine.

> And as Nigel pointed out,
>
>> Single object which returns an array from the has_many accessor.
> If I use 'join' only, I could get all the data for railways which only have 1 row of railway_station by using "railway.railway_station", but for railways which have more than 1 rows of railway_station, I had to use something like "railway.railway_station.0". But it always failed for "prefetch"
>
> The way I wanted it, is that, since my search code is like this,
>
> my $railways = $schema->resultset('Railway')->search(
> {
> 'me.railway_id' => { 'IN' => $selected_railway_ids },
> 'railway_station.main_flag' => 1, ## forgot to mention this earlier
> },
> {
>  join => 'railway_station',
>  prefetch => 'railway_station',
>  }
> );
> $c->stash->{railways} = [$railways->all];
>
>
> And although railway has 'has_many' rel, with the condition main_flag=1, only 1 or null railway_station should be returned for each railway, and therefore, I am hoping to access it by  [% railway.railway_station%]
>
> The way that my friend solved it, was to declare a select variable
>
>    my @select = (
>        qw/
>            railway_field_1
>            railway_field_2
>            main_flag   #from railway_station
>            railway_station_field1 #from railway_station
>          /
>    );
>
> and put it in the search condition like this:
>
> my $railways = $schema->resultset('Railway')->search(
> {
>  'me.railway_id' => { 'IN' => $selected_railway_ids },
>  'railway_station.main_flag' => 1, ## forgot to mention this earlier
> },
> {
>  select => \@select,
>  join => 'railway_station',
> }
> );

Basically skipping the prefetch which makes your data into railway_station 
objects, and fetching just the one value you need. Which is there is only 
one object, works fine.

> and he wasn't using prefetch at all. Now, I could access 'main flag' field by using [% railway.main_flag.%], instead of
> [% railway.railway_station.main_flag %]
> Any ideas why this happened?

TT.

Jess



More information about the DBIx-Class mailing list