Inherited relationships

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); }