added cascade_copy relationship attribute
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Row.pm
index 3606235..0d4a8a4 100644 (file)
@@ -236,9 +236,26 @@ Inserts a new row with the specified changes.
 
 sub copy {
   my ($self, $changes) = @_;
-  my $new = bless({ _column_data => { %{$self->{_column_data}}} }, ref $self);
+  $changes ||= {};
+  my $col_data = { %{$self->{_column_data}} };
+  foreach my $col (keys %$col_data) {
+    delete $col_data->{$col}
+      if $self->result_source->column_info($col)->{is_auto_increment};
+  }
+  my $new = bless({ _column_data => $col_data }, ref $self);
   $new->set_column($_ => $changes->{$_}) for keys %$changes;
-  return $new->insert;
+  $new->insert;
+  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);
+      }
+    }
+  }
+  $new;
 }
 
 =head2 store_column
@@ -278,17 +295,16 @@ sub inflate_result {
   PRE: foreach my $pre (keys %{$prefetch||{}}) {
     my $pre_source = $source->related_source($pre);
     $class->throw_exception("Can't prefetch non-existant relationship ${pre}") unless $pre_source;
-    my $fetched = $pre_source->result_class->inflate_result(
-                    $pre_source, @{$prefetch->{$pre}});
+    my $fetched;
+    unless ($pre_source->primary_columns == grep { exists $prefetch->{$pre}[0]{$_} 
+       and !defined $prefetch->{$pre}[0]{$_} } $pre_source->primary_columns)
+    {
+      $fetched = $pre_source->result_class->inflate_result(
+                      $pre_source, @{$prefetch->{$pre}});      
+    }
     my $accessor = $source->relationship_info($pre)->{attrs}{accessor};
     $class->throw_exception("No accessor for prefetched $pre")
       unless defined $accessor;
-    PRIMARY: foreach my $pri ($pre_source->primary_columns) {
-      unless (defined $fetched->get_column($pri)) {
-        undef $fetched;
-        last PRIMARY;
-      }
-    }
     if ($accessor eq 'single') {
       $new->{_relationship_data}{$pre} = $fetched;
     } elsif ($accessor eq 'filter') {