Fix updates with multi-create syntax
Jess Robinson [Sat, 10 Mar 2007 13:40:54 +0000 (13:40 +0000)]
lib/DBIx/Class/Row.pm
t/96multi_create.t

index dc1312d..24575f7 100644 (file)
@@ -36,7 +36,6 @@ passed objects.
 
 =cut
 
-## NB (JER) - this assumes set_from_related can cope with multi-rels
 ## It needs to store the new objects somewhere, and call insert on that list later when insert is called on this object. We may need an accessor for these so the user can retrieve them, if just doing ->new().
 ## This only works because DBIC doesnt yet care to check whether the new_related objects have been passed all their mandatory columns
 ## When doing the later insert, we need to make sure the PKs are set.
@@ -60,6 +59,7 @@ sub new {
     my ($related,$inflated);
     foreach my $key (keys %$attrs) {
       if (ref $attrs->{$key}) {
+        ## Can we extract this lot to use with update(_or .. ) ?
         my $info = $class->relationship_info($key);
         if ($info && $info->{attrs}{accessor}
           && $info->{attrs}{accessor} eq 'single')
@@ -84,7 +84,6 @@ sub new {
                 $new->{_rel_in_storage} = 0;
               }
             }
-#            $new->set_from_related($key, $others);
             $related->{$key} = $others;
             next;
         } elsif ($class->has_column($key)
@@ -144,6 +143,7 @@ sub insert {
                        %{$self->{_inflated_column} || {}});
   ## Should all be in relationship_data, but we need to get rid of the
   ## 'filter' reltype..
+  ## These are the FK rels, need their IDs for the insert.
   foreach my $relname (keys %related_stuff) {
     my $relobj = $related_stuff{$relname};
     if(ref $relobj ne 'ARRAY') {
@@ -169,6 +169,7 @@ sub insert {
     $self->store_column($pri => $id);
   }
 
+  ## Now do the has_many rels, that need $selfs ID.
   foreach my $relname (keys %related_stuff) {
     my $relobj = $related_stuff{$relname};
     if(ref $relobj eq 'ARRAY') {
@@ -232,7 +233,19 @@ sub update {
           my $rel = delete $upd->{$key};
           $self->set_from_related($key => $rel);
           $self->{_relationship_data}{$key} = $rel;          
-        } 
+        } elsif ($info && $info->{attrs}{accessor}
+            && $info->{attrs}{accessor} eq 'multi'
+            && ref $upd->{$key} eq 'ARRAY') {
+            my $others = delete $upd->{$key};
+            foreach my $rel_obj (@$others) {
+              if(!Scalar::Util::blessed($rel_obj)) {
+                $rel_obj = $self->create_related($key, $rel_obj);
+              }
+            }
+            $self->{_relationship_data}{$key} = $others; 
+#            $related->{$key} = $others;
+            next;
+        }
         elsif ($self->has_column($key)
           && exists $self->column_info($key)->{_inflate_info})
         {
index f7f5602..9edc1c6 100644 (file)
@@ -1,5 +1,5 @@
 use strict;
-use warnings;  
+use warnings;
 
 use Test::More;
 use lib qw(t/lib);
@@ -7,7 +7,7 @@ use DBICTest;
 
 my $schema = DBICTest->init_schema();
 
-plan tests => 4;
+plan tests => 6;
 
 my $cd2 = $schema->resultset('CD')->create({ artist => 
                                    { name => 'Fred Bloggs' },
@@ -27,3 +27,27 @@ my $artist = $schema->resultset('Artist')->create({ name => 'Fred 2',
                                                      });
 is(ref $artist->cds->first, 'DBICTest::CD', 'Created Artist with CDs');
 is($artist->cds->first->title, 'Music to code by', 'CD created correctly');
+
+# Add a new CD
+$artist->update({cds => [ $artist->cds, 
+                          { title => 'Yet another CD',
+                            year => 2006,
+                          },
+                        ],
+                });
+is(($artist->cds->search({}, { order_by => 'year' }))[0]->title, 'Yet another CD', 'Updated and added another CD');
+
+my $newartist = $schema->resultset('Artist')->find_or_create({ name => 'Fred 2'});
+
+is($newartist->name, 'Fred 2', 'Retrieved the artist');
+
+my $newartist2 = $schema->resultset('Artist')->find_or_create({ name => 'Fred 3',
+                                                                cds => [
+                                                                        { title => 'Noah Act',
+                                                                          year => 2007,
+                                                                        },
+                                                                       ],
+
+                                                              });
+
+is($newartist2->name, 'Fred 3', 'Created new artist with cds via find_or_create');