Re: setting up relationships
[prev]
[thread]
[next]
[Date index for 2004/06/21]
--3VRmKSg17yJg2MZg
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
On Mon, Jun 21, 2004 at 12:30:58 -0700, steve shapero wrote:
> hello list--
Hi!
> i am having some trouble setting up relationships for my database, which
> has a fair number of "lookup" tables. given these tables, i'm wondering
> how i can setup a relationship between them. also, any advice on how to
> use AutoLoader in this scenario would be great.
Class::DBI::Loader looks at your schema, and then creates some packages
for you.
Read the synopsis of Class::DBI::Loader [1]. In your case, using
my $loader =3D Class::DBI::Loader->new(
dsn =3D> $dsn,
namespace =3D> 'C'
);
you will be able to ask $loader what class was generated for the artist
table:
$loader->find_class('artist');
The class it will return would have been already loaded, so just doing
C::Artist->retrieve(1);
should have worked.
Class::DBI::AutoLoader is used a bit differently - it generates the
namespaces, period. There is no loader object, which you can harass. The
implementations are different though, and it looks like
Class::DBI::Loader is a little more robustly designed.
Neither of these sets up relationships. For this you have to do some
manual labor...
> in this scenario, a track has n number of artists, and an artist might
> have produced x number of tracks...
This is solved by mapping.
I'll assume you used CDBI::Loader with a namespace of 'C'.
Lets start with the lookup table:
package C::Track_Artsit; # [sic]
__PACKAGE__->has_a( artist =3D> 'C::Artist' );
__PACKAGE__->has_a( track =3D> 'C::Track' );
This definition of the relationship will let you take an object of class
C::Track_Artsit, lets call it $link, and know the associated artist and
track of that link:
$link->artist; # returns a C::Artist->retrieve() on the
# value of the 'artist' column
This basic relationship is then used by a mapping:
package C::Artist;
__PACKAGE__->has_many( tracks =3D> [ 'C::Track_Artsit' =3D> track ] );
What's happenning here is that an artist has many C::Track_Artsit. When
you call tracks, it retrieves all the C::Track_Artsit objects whose
'artist' column matches the primary key of an $artist.
To get this behavior, you just say
__PACKAGE__->has_many( tracks =3D> 'C::Track_Artsit' );
But that's not what we said.
The added bit is the mapping. Since you did not pass a class name to
has_many, but an array ref with a class name and a field name, what you
will actually be getting is not the C::Track_Artsit object, but a sort
of mapping, where each C::Track_Artsit object loaded will have ->track
called on it, and /that/'s what will be returned.
In effect, you do $artist->tracks, and CDBI loads all the lookups, and
then goes to the 'track' of each lookup, and gives you back a number of
C::Track objects.
The reason you get an object is because we previously told
C::Track_Artsit that it has_a C::Track in the column 'track', so the
foreign key is inflated.
1. http://search.cpan.org/~ikebe/Class-DBI-Loader-0.02/lib/Class/DBI/Loader=
=2Epm#SYNOPSIS
--=20
() Yuval Kogman <nothingmuch@xxxxxxxx.xxx> 0xEBD27418 perl hacker &
/\ kung foo master: /me has realultimatepower.net: neeyah!!!!!!!!!!!!
--3VRmKSg17yJg2MZg
Content-Type: application/pgp-signature
Content-Disposition: inline
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (Darwin)
iD8DBQFA10fTVCwRwOvSdBgRAkxGAKCYvl0wFVY8u+bKBLQUxEjq7KKPqwCgvxFp
hSKNORcQ4fXwMPg9/Z19wIk=
=TVzm
-----END PGP SIGNATURE-----
--3VRmKSg17yJg2MZg--
|
(message missing)
|