Inherited relationships
From ClassDBI
This problem was resolved in version 3.0.9 on Sep 23rd 2005, if you still encounter it re-open the bug and/or upgrade to a more recent version
-- Aaron Trevena
Cut & paste from https://rt.cpan.org/NoAuth/Bug.html?id=14878 and some rough edges cleaned up:
If you declare relationships in your base class and then again in a data class, the __meta_info hash will end up containing hash references that are shared among classes. This severely buggers up the relationship definitions, of course.
It's because this (in Class::DBI::_extend_meta):
my %hash = %{ $class->__meta_info || {} };
$hash{$type}->{$subtype} = $val;
$class->__meta_info(\%hash);
dereferences the main metadata hash, but it doesn't dereference $hash{$type}. If there's already a hashref there - because we're inheriting from a class that defined a relationship of that type - then it will remain shared.
In short, if you define a has_a relationship in your base class then all the has_a relationships of all your classes will be assigned to all your classes. It isn't such an odd thing to do, either. I triggered the bug with this in a base class:
__PACKAGE__->columns(DATE => qw( date cdate )); __PACKAGE__->has_a( date => 'Delivery::Machinery::Date' ); __PACKAGE__->has_a( cdate => 'Delivery::Machinery::Date' );
which is true of all the classes in this particular application and useful to centralise.
The fix is easy, if a little bodgy. Just add an extra dereference to Class::DBI::_extend_meta:
sub _extend_meta {
my ($class, $type, $subtype, $val) = @_;
my %hash = %{ $class->__meta_info || {} };
my %subhash = %{ $hash{$type} || {} };
$subhash{$subtype} = $val;
$hash{$type} = \%subhash;
$class->__meta_info(\%hash);
}

