[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