From: Ash Berlin Date: Thu, 15 Nov 2007 13:52:58 +0000 (+0000) Subject: Fix t/82cascade_copy.t X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=3568822060ed84cfa974be736a3f0e049e9978a5;p=dbsrgits%2FDBIx-Class-Historic.git Fix t/82cascade_copy.t --- diff --git a/Changes b/Changes index 53a2293..b1b63a5 100644 --- a/Changes +++ b/Changes @@ -17,6 +17,8 @@ Revision history for DBIx::Class - ResultSource::reverse_relationship_info can distinguish between sources using the same table - Row::insert will now not fall over if passed duplicate related objects + - Row::copy will not fall over if you have two relationships to the + same source with a unique constraint on it 0.08007 2007-09-04 19:36:00 - patch for Oracle datetime inflation (abram@arin.net) diff --git a/lib/DBIx/Class/Row.pm b/lib/DBIx/Class/Row.pm index 6ac92bf..96c766e 100644 --- a/lib/DBIx/Class/Row.pm +++ b/lib/DBIx/Class/Row.pm @@ -532,15 +532,29 @@ sub copy { $new->result_source($self->result_source); $new->set_columns($changes); $new->insert; + + # Its possible we'll have 2 relations to the same Source. We need to make + # sure we don't try to insert the same row twice esle we'll violate unique + # constraints + my $rels_copied = {}; + foreach my $rel ($self->result_source->relationships) { my $rel_info = $self->result_source->relationship_info($rel); - if ($rel_info->{attrs}{cascade_copy}) { - my $resolved = $self->result_source->resolve_condition( - $rel_info->{cond}, $rel, $new); - foreach my $related ($self->search_related($rel)) { - $related->copy($resolved); - } + + next unless $rel_info->{attrs}{cascade_copy}; + + my $resolved = $self->result_source->resolve_condition( + $rel_info->{cond}, $rel, $new + ); + + my $copied = $rels_copied->{ $rel_info->{source} } ||= {}; + foreach my $related ($self->search_related($rel)) { + my $id_str = join("\0", $related->id); + next if $copied->{$id_str}; + $copied->{$id_str} = 1; + my $rel_copy = $related->copy($resolved); } + } return $new; }