applied patch from davinch: fix bug with create_multi not inserting non-storage objects
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Row.pm
index e5fb4c9..7195bba 100644 (file)
@@ -76,8 +76,10 @@ sub new {
           my $rel_obj = delete $attrs->{$key};
           if(!Scalar::Util::blessed($rel_obj)) {
             $rel_obj = $new->find_or_new_related($key, $rel_obj);
-            $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage);
           }
+
+          $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage);
+
           $new->set_from_related($key, $rel_obj);        
           $related->{$key} = $rel_obj;
           next;
@@ -90,6 +92,8 @@ sub new {
               $rel_obj = $new->new_related($key, $rel_obj);
               $new->{_rel_in_storage} = 0;
             }
+
+            $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage);
           }
           $related->{$key} = $others;
           next;
@@ -150,9 +154,7 @@ sub insert {
   my %related_stuff = (%{$self->{_relationship_data} || {}}, 
                        %{$self->{_inflated_column} || {}});
 
-  if(!$self->{_rel_in_storage})
-  {
-
+  if(!$self->{_rel_in_storage}) {
     $source->storage->txn_begin;
 
     # The guard will save us if we blow out of this scope via die
@@ -166,24 +168,38 @@ sub insert {
     my @pri = $self->primary_columns;
 
     REL: foreach my $relname (keys %related_stuff) {
-      my $keyhash = $source->resolve_condition(
-                      $source->relationship_info($relname)->{cond},
-                      undef, 1
-                    ); # the above argset gives me the dependent cols on self
+
+      my $rel_obj = $related_stuff{$relname};
+
+      next REL unless (Scalar::Util::blessed($rel_obj)
+                       && $rel_obj->isa('DBIx::Class::Row'));
+
+      my $cond = $source->relationship_info($relname)->{cond};
+
+      next REL unless ref($cond) eq 'HASH';
+
+      # map { foreign.foo => 'self.bar' } to { bar => 'foo' }
+
+      my $keyhash = { map { my $x = $_; $x =~ s/.*\.//; $x; } reverse %$cond };
 
       # assume anything that references our PK probably is dependent on us
-      # rather than vice versa
+      # rather than vice versa, unless the far side is (a) defined or (b)
+      # auto-increment
 
       foreach my $p (@pri) {
-        next REL if exists $keyhash->{$p};
+        if (exists $keyhash->{$p}) {
+          warn $keyhash->{$p};
+          unless (defined($rel_obj->get_column($keyhash->{$p}))
+                  || $rel_obj->column_info($keyhash->{$p})
+                             ->{is_auto_increment}) {
+            next REL;
+          }
+        }
       }
 
-      my $rel_obj = $related_stuff{$relname};
-      if(Scalar::Util::blessed($rel_obj) && $rel_obj->isa('DBIx::Class::Row')) {
-        $rel_obj->insert();
-        $self->set_from_related($relname, $rel_obj);
-        delete $related_stuff{$relname};
-      }
+      $rel_obj->insert();
+      $self->set_from_related($relname, $rel_obj);
+      delete $related_stuff{$relname};
     }
   }
 
@@ -208,8 +224,7 @@ sub insert {
     $self->store_column($auto_pri[$_] => $ids[$_]) for 0 .. $#ids;
   }
 
-  if(!$self->{_rel_in_storage})
-  {
+  if(!$self->{_rel_in_storage}) {
     ## Now do the has_many rels, that need $selfs ID.
     foreach my $relname (keys %related_stuff) {
       my $rel_obj = $related_stuff{$relname};