Multilevel find_or_(multi)create got inadvertently broken
Peter Rabbitson [Tue, 16 Sep 2014 08:04:59 +0000 (10:04 +0200)]
Relax the check of what we feed to the relcond resolver

lib/DBIx/Class/ResultSource.pm
t/multi_create/find_or_multicreate.t [new file with mode: 0644]

index 4669926..2d54ec0 100644 (file)
@@ -1907,8 +1907,9 @@ sub _resolve_relationship_condition {
       $args->{foreign_values} = { $args->{foreign_values}->get_columns };
     }
     elsif (! defined $args->{foreign_values} or ref $args->{foreign_values} eq 'HASH') {
+      my $ri = { map { $_ => 1 } $rel_rsrc->relationships };
       my $ci = $rel_rsrc->columns_info;
-      ! exists $ci->{$_} and $self->throw_exception(
+      ! exists $ci->{$_} and ! exists $ri->{$_} and $self->throw_exception(
         "Key '$_' supplied as 'foreign_values' is not a column on related source '@{[ $rel_rsrc->source_name ]}'"
       ) for keys %{ $args->{foreign_values} ||= {} };
     }
diff --git a/t/multi_create/find_or_multicreate.t b/t/multi_create/find_or_multicreate.t
new file mode 100644 (file)
index 0000000..762b962
--- /dev/null
@@ -0,0 +1,71 @@
+use strict;
+use warnings;
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+
+my $schema = DBICTest->init_schema( no_populate => 1 );
+
+my $t11 = $schema->resultset('Track')->find_or_create({
+  trackid => 1,
+  title => 'Track one cd one',
+  cd => {
+    year => 1,
+    title => 'CD one',
+    very_long_artist_relationship => {
+      name => 'Artist one',
+    }
+  }
+});
+
+my $t12 = $schema->resultset('Track')->find_or_create({
+  trackid => 2,
+  title => 'Track two cd one',
+  cd => {
+    title => 'CD one',
+    very_long_artist_relationship => {
+      name => 'Artist one',
+    }
+  }
+});
+
+# FIXME - MC should be smart enough to infer this on its own...
+$schema->resultset('Artist')->create({ name => 'Artist two' });
+
+my $t2 = $schema->resultset('Track')->find_or_create({
+  trackid => 3,
+  title => 'Track one cd one',
+  cd => {
+    year => 1,
+    title => 'CD one',
+    very_long_artist_relationship => {
+      name => 'Artist two',
+    }
+  }
+});
+
+is_deeply(
+  $schema->resultset('Artist')->search({}, {
+    prefetch => { cds => 'tracks' },
+    order_by => 'tracks.title',
+  })->all_hri,
+  [
+    { artistid => 1, charfield => undef, name => "Artist one", rank => 13, cds => [
+      { artist => 1, cdid => 1, genreid => undef, single_track => undef, title => "CD one", year => 1, tracks => [
+        { cd => 1, last_updated_at => undef, last_updated_on => undef, position => 1, title => "Track one cd one", trackid => 1 },
+        { cd => 1, last_updated_at => undef, last_updated_on => undef, position => 2, title => "Track two cd one", trackid => 2 },
+      ]},
+    ]},
+    { artistid => 2, charfield => undef, name => "Artist two", rank => 13, cds => [
+      { artist => 2, cdid => 2, genreid => undef, single_track => undef, title => "CD one", year => 1, tracks => [
+        { cd => 2, last_updated_at => undef, last_updated_on => undef, position => 1, title => "Track one cd one", trackid => 3 },
+      ]},
+    ]},
+  ],
+  'Expected state of database after several find_or_create rounds'
+);
+
+
+done_testing;
+