Fix t/82cascade_copy.t
Ash Berlin [Thu, 15 Nov 2007 13:52:58 +0000 (13:52 +0000)]
Changes
lib/DBIx/Class/Row.pm

diff --git a/Changes b/Changes
index 53a2293..b1b63a5 100644 (file)
--- 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)
index 6ac92bf..96c766e 100644 (file)
@@ -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;
 }