[Dbix-class] Ok, let's begin

Matt S Trout dbix-class at trout.me.uk
Thu Sep 22 15:09:09 CEST 2005


On Wed, Sep 21, 2005 at 11:33:51PM +0200, Krzysztof Krzyzaniak wrote:
> Ok, part 2.
> 
> Standard example, Record & Tracks. Let's train some has_many (it's 
> probably different from Class::DBI because example doesn't work).
> 
> package TrackCD::M::DBIC::Record;
> 
> use strict;
> use base qw/TrackCD::M::DBIC/;
> 
> __PACKAGE__->table('record');
> __PACKAGE__->add_columns (
>       qw/rec_id rec_time rec_cddbid rec_artist rec_title rec_notrack 
> rec_genre rec_year rec_timestamp/
> );
> 
> __PACKAGE__->set_primary_key('rec_id');
> 
> __PACKAGE__->has_many (
>       'tracks' => 'TrackCD::M::DBIC::Track'
> );
> 
> 
> 1;
> 
> and tracks:
> 
> package TrackCD::M::DBIC::Track;
> 
> use strict;
> use base qw/TrackCD::M::DBIC/;
> 
> __PACKAGE__->table('track');
> __PACKAGE__->add_columns(qw/rec_id trck_id trck_title trck_time 
> trck_position trck_extinfo/);
> __PACKAGE__->set_primary_key('trck_id');
> 
> 1;
> 
> They are connected with 'rec_id' field.
> 
> But during loading I have:
> 
> Couldn't load "TrackCD::M::DBIC::Record", "Unable to resolve foreign key 
> for has_many from TrackCD::M::DBIC::Record to TrackCD::M::DBIC::Track at 
> (eval 95) line 3

That's the has_many inference stuff not being as smart as it might be. It
will have guessed at a field called 'record' as the FK on the track table,
not found that and failed.

We should probably consider having it try the PK of the current table as the
name of the FK on the related table (which would make your example above
work), but in the meantime you can set the FK explicitly -

__PACKAGE__->has_many('tracks' => 'TrackCD::M::DBIC::Track' => 'rec_id');

(I prefer the explicit form myself, but I'm using code-generators :)

You also probably want (on ::Track) either

__PACKAGE__->belongs_to('rec_id' => 'TrackCD::M::DBIC::Record');

which will inflate the rec_id column, or

__PACKAGE__->belongs_to('record' => 'TrackCD::M::DBIC::Record',
                          { 'foreign.rec_id' => 'self.rec_id' } );

which will set up the same relationship but with a new accessor called
'record' (so $track->rec_id will still just return the ID itself but
$track->record and $track->record($record) will work as expected).

-- 
     Matt S Trout       Specialists in perl consulting, web development, and
  Technical Director    UNIX/Linux systems architecture and automation. Mail
Shadowcat Systems Ltd.  mst (at) shadowcatsystems.co.uk for more information

 + Help us build a better perl ORM: http://dbix-class.shadowcatsystems.co.uk/ +



More information about the Dbix-class mailing list