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

Matt S Trout dbix-class at trout.me.uk
Sat Mar 8 16:47:09 GMT 2008


On Wed, Feb 27, 2008 at 07:55:32PM +0900, 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 -%]
> 
> 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%]

If it's a has many, please declare it with a plural.

If you know there'll only be one in certain cases (assuming you renamed the
has_many rel to 'railway_stations'), add

sub railway_stations {
  shift->railway_stations->first;
}

and everything will work fine.
 
> 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',
>  }
>  );
> 
> 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?

DBIx::Class has no way of knowing the restricted form of the rel is 0 or 1.

Use the trick described above instead.

-- 
      Matt S Trout       Need help with your Catalyst or DBIx::Class project?
   Technical Director                    http://www.shadowcat.co.uk/catalyst/
 Shadowcat Systems Ltd.  Want a managed development or deployment platform?
http://chainsawblues.vox.com/            http://www.shadowcat.co.uk/servers/



More information about the DBIx-Class mailing list