while ( my($col, $value) = each %implied ) {
my $vref = ref $value;
- if ($vref eq 'HASH' && keys(%$value) && (keys %$value)[0] eq '=') {
- $new_data{$col} = $value->{'='};
+ if ($vref eq 'HASH') {
+ if (keys(%$value) && (keys %$value)[0] eq '=') {
+ $new_data{$col} = $value->{'='};
+ }
+ # in a complex condition, set_from_related needs to override
+ # the columns that are involved.
+ elsif (!exists $data->{$col} &&
+ !exists $data->{"$alias.$col"}) {
+ $self->throw_exception("unable to set_from_related via complex condition on column(s): '$col'");
+ }
}
elsif( !$vref or $vref eq 'SCALAR' or blessed($value) ) {
$new_data{$col} = $value;
);
__PACKAGE__->has_many(
- cds_80s_noopt => 'DBICTest::Schema::CD',
+ cds_90s => 'DBICTest::Schema::CD',
sub {
my $args = shift;
return (
{ "$args->{foreign_alias}.artist" => { -ident => "$args->{self_alias}.artistid" },
- "$args->{foreign_alias}.year" => { '>' => 1979, '<' => 1990 },
+ "$args->{foreign_alias}.year" => { '>' => 1989, '<' => 2000 },
}
);
- },
+ }
);
+
__PACKAGE__->has_many(
- cds_90s => 'DBICTest::Schema::CD',
+ cds_84 => 'DBICTest::Schema::CD',
sub {
my $args = shift;
return (
{ "$args->{foreign_alias}.artist" => { -ident => "$args->{self_alias}.artistid" },
- "$args->{foreign_alias}.year" => { '>' => 1989, '<' => 2000 },
+ "$args->{foreign_alias}.year" => 1984,
+ },
+ $args->{self_rowobj} && {
+ "$args->{foreign_alias}.artist" => $args->{self_rowobj}->artistid,
+ "$args->{foreign_alias}.year" => 1984,
}
);
}
}
my @cds_80s = $artist->cds_80s;
-is(@cds_80s, 6, '6 80s cds found');
+is(@cds_80s, 6, '6 80s cds found (1980 - 1985)');
+map { ok($_->year < 1990 && $_->year > 1979) } @cds_80s;
my @cds_90s = $artist2->cds_90s;
-is(@cds_90s, 6, '6 90s cds found even with non-optimized search');
+is(@cds_90s, 6, '6 90s cds found (1990 - 1995) even with non-optimized search');
+map { ok($_->year < 2000 && $_->year > 1989) } @cds_90s;
-map { ok($_->year < 1990 && $_->year > 1979) } @cds_80s;
+# search for all artists prefetching published cds in the 80s...
+#####
+# the join must be a prefetch, but it can't work until the collapse rewrite is finished
+# (right-side vs left-side order)
+#####
+TODO: {
+ local $TODO = "Replace the join below with this when we fix the collapser";
+ lives_ok {
+ my @all_artists_with_80_cds = $schema->resultset("Artist")->search
+ ({ 'cds_80s.cdid' => { '!=' => undef } }, { prefetch => 'cds_80s' })->all;
+ } 'prefetchy-fetchy-fetch?';
+}
+my @all_artists_with_80_cds = $schema->resultset("Artist")->search
+ ({ 'cds_80s.cdid' => { '!=' => undef } }, { join => 'cds_80s', distinct => 1 });
+
+is_deeply(
+ [ sort ( map { $_->year } map { $_->cds_80s->all } @all_artists_with_80_cds ) ],
+ [ sort (1980..1989, 1980..1985) ],
+ '16 correct cds found'
+);
+
+# try to create_related a 80s cd
+throws_ok {
+ $artist->create_related('cds_80s', { title => 'related creation 1' });
+} qr/\Qunable to set_from_related via complex 'cds_80s' condition on column(s): 'year'/, 'Create failed - complex cond';
+
+# now supply an explicit arg overwriting the ambiguous cond
+my $id_2020 = $artist->create_related('cds_80s', { title => 'related creation 2', year => '2020' })->id;
+is(
+ $schema->resultset('CD')->find($id_2020)->title,
+ 'related creation 2',
+ '2020 CD created correctly'
+);
+
+# try a default year from a specific rel
+my $id_1984 = $artist->create_related('cds_84', { title => 'related creation 3' })->id;
+is(
+ $schema->resultset('CD')->find($id_1984)->title,
+ 'related creation 3',
+ '1984 CD created correctly'
+);
+
+# try a specific everything via a non-simplified rel
+throws_ok {
+ $artist->create_related('cds_90s', { title => 'related_creation 4', year => '2038' });
+} qr/\Qunable to set_from_related - no simplified condition available for 'cds_90s'/, 'Create failed - non-simplified rel';
-# search for all artists prefetching published cds in the 80s...
-my @all_cds_80s = $schema->resultset("Artist")->search
- ({ 'cds_80s_noopt.cdid' => { '!=' => undef } }, { join => 'cds_80s_noopt' });
-is(@all_cds_80s, 16, '16 cds found even with the non-optimized search');
+# Do a self-join last-entry search
my @last_track_ids;
for my $cd ($schema->resultset('CD')->search ({}, { order_by => 'cdid'})->all) {
push @last_track_ids, $cd->tracks