From: Luke Saunders Date: Tue, 6 Jun 2006 20:48:37 +0000 (+0000) Subject: tightened up deep search_related X-Git-Tag: v0.07002~75^2~130^2~1 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=b7439887af8d68878363e3f157ea95595764c548;p=dbsrgits%2FDBIx-Class.git tightened up deep search_related --- diff --git a/Changes b/Changes index 3325a53..78309b9 100644 --- a/Changes +++ b/Changes @@ -2,6 +2,7 @@ Revision history for DBIx::Class 0.06999_02 sometime? - Fixed up POD::Coverage tests, filled in some POD holes + - Fixed resultset bugs to do with related searches 0.06999_01 2006-05-28 17:19:30 - add automatic naming of unique constraints diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 75e66a7..7a0d302 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -165,9 +165,23 @@ sub search_rs { my $our_attrs = ($attrs->{_parent_attrs}) ? { %{$attrs->{_parent_attrs}} } : { %{$self->{attrs}} }; my $having = delete $our_attrs->{having}; + # XXX this is getting messy + if ($attrs->{_live_join_stack} || $our_attrs->{_live_join_stack}) { + my $live_join = $attrs->{_live_join_stack} || $our_attrs->{_live_join_stack}; + foreach (reverse @{$live_join}) { + $attrs->{_live_join_h} = (defined $attrs->{_live_join_h}) ? { $_ => $attrs->{_live_join_h} } : $_; + } + } + # merge new attrs into old foreach my $key (qw/join prefetch/) { next unless (exists $attrs->{$key}); + if ($attrs->{_live_join_stack} || $our_attrs->{_live_join_stack}) { + my $live_join = $attrs->{_live_join_stack} || $our_attrs->{_live_join_stack}; + foreach (@{$live_join}) { + $attrs->{$key} = { $_ => $attrs->{$key} }; + } + } if ($attrs->{_live_join} || $our_attrs->{_live_join}) { $attrs->{$key} = { ($attrs->{_live_join}) ? $attrs->{_live_join} : $our_attrs->{_live_join} => $attrs->{$key} }; } @@ -179,7 +193,8 @@ sub search_rs { delete $attrs->{$key}; } - $our_attrs->{join} = $self->_merge_attr($our_attrs->{join}, $attrs->{_live_join}, 1) if ($attrs->{_live_join}); + $our_attrs->{join} = $self->_merge_attr($our_attrs->{join}, $attrs->{_live_join_h}, 1) if ($attrs->{_live_join_h}); + if (exists $our_attrs->{prefetch}) { $our_attrs->{join} = $self->_merge_attr($our_attrs->{join}, $our_attrs->{prefetch}, 1); } @@ -1563,15 +1578,19 @@ sub related_resultset { "' has no such relationship ${rel}") unless $rel_obj; #die Dumper $self->{attrs}; + my $live_join_stack = $self->{attrs}->{_live_join_stack} || []; + push(@{$live_join_stack}, $rel); + my $rs = $self->result_source->schema->resultset($rel_obj->{class} )->search( undef, { select => undef, as => undef, #join => $rel, _live_join => $rel, + _live_join_stack => $live_join_stack, _parent_attrs => $self->{attrs}} - ); - + ); + # keep reference of the original resultset $rs->{_parent_rs} = ($self->{_parent_rs}) ? $self->{_parent_rs} : $self->result_source; return $rs; diff --git a/t/90join_torture.t b/t/90join_torture.t index 4a8aa4e..c5a4bcf 100644 --- a/t/90join_torture.t +++ b/t/90join_torture.t @@ -7,11 +7,10 @@ use DBICTest; my $schema = DBICTest->init_schema(); -plan tests => 9; +plan tests => 10; my @rs1a_results = $schema->resultset("Artist")->search_related('cds', {title => 'Forkful of bees'}, {order_by => 'title'}); is($rs1a_results[0]->title, 'Forkful of bees', "bare field conditions okay after search related"); - my $rs1 = $schema->resultset("Artist")->search({ 'tags.tag' => 'Blue' }, { join => {'cds' => 'tracks'}, prefetch => {'cds' => 'tags'} }); my @artists = $rs1->all; cmp_ok(@artists, '==', 1, "Two artists returned"); @@ -38,11 +37,19 @@ my $record_rs = $schema->resultset("Artist")->search(undef, { join => 'cds' })-> my $record_jp = $record_rs->next; ok($record_jp, "prefetch on same rel okay"); -my $cd = $schema->resultset("CD")->find(1); -my $producers = $cd->producers; -is($producers->find(2)->name, 'Bob The Builder', "find on many to many okay"); +my $artist = $schema->resultset("Artist")->find(1); +my $cds = $artist->cds; +is($cds->find(2)->title, 'Forkful of bees', "find on has many rs okay"); + +my $cd = $cds->search({'me.title' => 'Forkful of bees'}, { prefetch => 'tracks' })->first; +my @tracks = $cd->tracks->all; +is(scalar(@tracks), 3, 'right number of prefetched tracks after has many'); + +# causes ambig col error due to order_by +#my $tracks_rs = $cds->search_related('tracks', { 'tracks.position' => '2', 'disc.title' => 'Forkful of bees' }); +#my $first_tracks_rs = $tracks_rs->first; -my @prods = $producers->search({name => 'Bob The Builder'}, { prefetch => 'producer_to_cd' })->all; -is($prods[0]->name, 'Bob The Builder', 'prefetch after has_many rel okay'); +my ($track) = $schema->resultset("Artist")->search({ name => 'Caterwauler McCrae' })->search_related('cds', { year => '2001'})->search_related('tracks', { 'position' => '2' })->all; +is($track->trackid, '5', 'search related on search related okay'); 1; diff --git a/t/lib/DBICTest/Schema/Producer.pm b/t/lib/DBICTest/Schema/Producer.pm index 26e140e..036f9f2 100644 --- a/t/lib/DBICTest/Schema/Producer.pm +++ b/t/lib/DBICTest/Schema/Producer.pm @@ -17,8 +17,4 @@ __PACKAGE__->add_columns( __PACKAGE__->set_primary_key('producerid'); __PACKAGE__->add_unique_constraint(prod_name => [ qw/name/ ]); -__PACKAGE__->has_many( - producer_to_cd => 'DBICTest::Schema::CD_to_Producer' => 'producer' -); - 1;