CassJ has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, Using CDBI, I have the following relationships defined:
WebR::M::CDBI::DatatypeRelationship->has_a(parent=>'WebR::M::CDBI::Dat +atype'); WebR::M::CDBI::DatatypeRelationship->has_a(child=>'WebR::M::CDBI::Data +type'); WebR::M::CDBI::Datatype->has_many(parents=>['WebR::M::CDBI::DatatypeRe +lationship'=> 'parent'], 'child'); WebR::M::CDBI::Datatype->has_many(children=>['WebR::M::CDBI::DatatypeR +elationship'=>'child'], 'parent');
When I try to delete a datafile, the cascade delete appears to work for the entries in the relationship table where that datafile is parent, but not where it is child. I had assumed that both would be deleted. Is this how it's supposed to work? Am I missing something obvious? Thanks, Cxx

Replies are listed 'Best First'.
Re: Class::DBI many to many delete
by Khen1950fx (Canon) on Jul 17, 2006 at 23:03 UTC
    It should work. According to the docs, the default for cascading delete is to delete the child if the parent is deleted; but it's not working here. So, we have to work around it.

    Class::DBI doesn't support Many to Many right now. The module's author does say that you can manually set up the relationships and get some measure of control by writing a Class::DBI::Cascade::Plugin::Nullify and inserting it into the relationship:

    WebR::M::CDBI::Datatype->has_many(children=>['WebR::M::CDBI::DatatypeR +elationship'=>'child"], 'parent', { cascade => 'Class::DBI::Cascade::Plugin::Nullify' });

    Try it and see if that works. I hope this helps.

      Odd. This works fine:
      WebR::M::CDBI::DatafileRelationship->has_a(child=>'WebR::M::CDBI:: +Datafile'); WebR::M::CDBI::DatafileRelationship->has_a(parent=>'WebR::M::CDBI: +:Datafile'); WebR::M::CDBI::Datafile->has_many(parents=>['WebR::M::CDBI::Datafi +leRelationship' => 'parent'],'child', { cascade => 'Class::DBI::Cascade::Delete'}); WebR::M::CDBI::Datafile->has_many(children=>['WebR::M::CDBI::Dataf +ileRelationship' => 'child'],'parent', { cascade => 'Class::DBI::Cascade::Delete'} );
      Ah - and if I do
      WebR::M::CDBI::DatafileRelationship->has_a(child=>'WebR::M::CDBI:: +Datafile', {cascade=>'Class::DBI::Cascade::Delete'});
      then the child datafiles get deleted too. Great! thanks! And, for the has_many relationships where I just want the FK to be nulled, rather than the record deleted:
      package Class::DBI::Cascade::Nullify; use base 'Class::DBI::Cascade::None'; use Data::Dumper; sub cascade { my ($self, $obj) = @_; my $fk =$self->{_rel}->args->{foreign_key}; foreach ($self->foreign_for($obj)){ $_->$fk(undef); $_->update; } } 1;
Re: Class::DBI many to many delete
by perrin (Chancellor) on Jul 17, 2006 at 15:39 UTC
    That looks like it should work. Do you get any errors, or does it just not delete them?
      No errors. It just doesn't delete. I'll go investigate further. I just wanted to be sure I hadn't misunderstood the expected behaviour, before I spend ages digging around working out what else could be broken.