[prev] [thread] [next] [Date index for 2004/06/30]
This is a multi-part message in MIME format. --------------010400070700060308070404 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Hi, I'm trying to subclass our Class::DBI classes to allow us to run lots of slightly different versions of our application for different customers on one server. However we've come across a couple of problems with relationships. (i) Adding a new relationship to the subclass seems to impact it's parent. For example if CD has a artist_id Artist, if we were to add a subclass of CD, ShopA::CD which has an artist_id ShopA::Artist then the CD artist_id also changes it's foreign class to ShopA::Artist. (ii) ShopA::Artist can't retrieve ShopA::CD through a cds method as it is the same one that Artist / CD uses. This is due to a line in Class::DBI::Relationship $class->can($accessor) and return $class->_carp("$accessor method already exists in $class\n"); which we patch to be defined &{"$class\::$accessor"} and return $class->_carp("$accessor method already exists in $class\n"); However we still get the same problem of Artist->cds returning ShopA::CD. It seems that the accessor is the unique key for the relationship and if one exists in a subclass then that will be changed rather than creating a new one. I've attached a simple example script which uses SQLite to show these issues. Are we doing something fundamentally wrong / is there a better way to do this ? Cheers, Mark. --------------010400070700060308070404 Content-Type: text/x-perl; name="test.pl" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="test.pl" use strict; use warnings; package Data; use base 'Class::DBI'; use File::Temp qw/tempfile/; my (undef, $DB) = tempfile(); my @DSN = ("dbi:SQLite:dbname=$DB", '', '', { AutoCommit => 1 }); END { unlink $DB if -e $DB } __PACKAGE__->connection(@DSN); package CD; use base 'Data'; __PACKAGE__->table('cd'); __PACKAGE__->columns(All => qw/id artist_id title/); __PACKAGE__->has_a(artist_id => 'Artist'); package Artist; use base 'Data'; __PACKAGE__->table('artist'); __PACKAGE__->columns(All => qw/id name/); __PACKAGE__->has_many(cds => 'CD'); package ShopA::CD; use base 'CD'; __PACKAGE__->table('shopa_cd'); __PACKAGE__->has_a(artist_id => 'ShopA::Artist'); package ShopA::Artist; use base 'Artist'; __PACKAGE__->table('shopa_artist'); __PACKAGE__->has_many(cds2 => 'ShopA::CD'); package Main; Data->db_Main->do(qq{ CREATE TABLE cd ( id int, artist_id int, title char(50) ) }); Data->db_Main->do(qq{ CREATE TABLE shopa_cd ( id int, artist_id int, title char(50) ) }); Data->db_Main->do(qq{ CREATE TABLE artist ( id int, name char(50) ) }); Data->db_Main->do(qq{ CREATE TABLE shopa_artist ( id int, name char(50) ) }); Artist->create({'id' => 1, name=>'Pixies'}); CD->create({'id' => 1, 'artist_id' => 1, title=>'Doolittle'}); ShopA::Artist->create({'id' => 1, name=>'Chikinki'}); my $cd = CD->retrieve(1); printf("%s by %s\n",$cd->title,$cd->artist_id->name); printf("CD meta info has a foreign class of %s\n", CD->meta_info('has_a' => 'artist_id')->foreign_class); --------------010400070700060308070404--
Subclassing problems with relationships
|
Generated at 11:34 on 01 Dec 2004 by mariachi v0.52