From: Peter Rabbitson Date: Tue, 16 Sep 2014 08:04:59 +0000 (+0200) Subject: Multilevel find_or_(multi)create got inadvertently broken X-Git-Tag: v0.082800~37 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class.git;a=commitdiff_plain;h=e084cb2bccea6e55372bb772ab02b7c9804542a1 Multilevel find_or_(multi)create got inadvertently broken Relax the check of what we feed to the relcond resolver --- diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index 4669926..2d54ec0 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -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 index 0000000..762b962 --- /dev/null +++ b/t/multi_create/find_or_multicreate.t @@ -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; +