Re: many2many
[prev]
[thread]
[next]
[Date index for 2005/04/12]
Hi Will--
Thanks, I got the many2many to work and I agree with you about the
naming conventions. I was using tables designed by someone else.
Now that I've got that working, I am back to getting cdbi factory to
work, but I can't seem to get it initialized correctly. The code has:
use base 'Class::DBI::Factory';
my $rebase = Class::DBI::Factory->new;
$rebase->set_db ({db_type => 'mysql',
db_name => 'rebase:localhost',
db_username => 'barry',
db_password => '',
});
$rebase->use_classes (qw/Enzyme Site EnzymeSite/);
print "db_name: " . $rebase->db_name . "\n";
but then I get the output:
Use of uninitialized value in concatenation (.) or string at
C:\Development\Perl\try\Tisdall\try_many2many.pl line 26.
db_name:
Set_db did not initialize the values for db name, username and password
even thought I used the same values when I used class::bdi->set_db. I also
tried
db_type => 'dbi:mysql',
in the factory set_db but that didn't help either.
TIA
Barry
----- Original Message -----
From: "William Ross" <will@xxxxxxx.xxx>
To: "Barry Dancis" <bdancis@xxxxxxx.xxx>
Cc: "class dbi list" <cdbi-talk@xxxxxx.xxxxx.xxx>
Sent: Monday, April 11, 2005 2:58 PM
Subject: Re: many2many
On 11 Apr 2005, at 17:46, Barry Dancis wrote:
> I am trying to implement a many to many relationship with
>
> #=============================
> {package Sites;
> Sites->has_many (siteenzymes => ['EnzymeSites' => 'enzid']);
>
> #=============================
> {package Enzymes;
> Enzymes->has_many (enzsites => ['EnzymeSites' => 'siteid']);
>
> #=============================
> {package EnzymeSites;
> EnzymeSites->columns(Primary => qw/ siteid enzid /);
> EnzymeSites->has_a (enzid => 'Enzymes');
> EnzymeSites->has_a (siteid => 'Sites');
>
> but when I execute:
>
> my $enzyme = Enzymes->retrieve(enzyme => 'TstI');
> my @sites = $enzyme->enzsites;
> I get the error:
>
> enzymes is not a column of EnzymeSites
The foreign class column name in a has_many relationship defaults to
the moniker of the calling class, on the reasonable assumption that
when a cd has many tracks, the cd of the track will be recorded in a
column called 'cd'. This is in the docs.
If i remember rightly, the moniker of a class defaults to the name of
its data table if no other moniker is declared. I don't think this is
in the docs.
Your Enzymes class is declaring a has_many relationship with
EnzymeSites. The extra [] clause just tells that relationship object to
return a column of the EnzymeSites object rather than returning the
whole object.
The data table for your Enzyme class is called 'enzymes'. By default
the has_many relationship will get that as the moniker and look for a
column with that name in the EnzymeSites class, but the real name of
the column is 'enz_id'. To avoid this trouble, you just have to specify
the column name. To avoid future trouble, I'd specify the class moniker
too:
Enzymes->moniker('enzyme');
Enzymes->has_many(enzsites => ['EnzymeSites' => 'siteid'], 'enzid');
Sites->has_many (siteenzymes => ['EnzymeSites' => 'enzid'], 'siteid');
Personally I also avoid the 'id' suffix on column names: it describes
the contents of the column well enough, but becomes confusing when the
column is inflated. In your case, it leads to statements like:
my $site_id = $enzyme->site_id->siteid;
But that's very much a question of taste, and there are plenty here who
would disagree.
best
Will
ps. Tony, didn't the moniker used to de-pluralise itself? Or did I
imagine that?