From: Luke Saunders Date: Tue, 6 Jun 2006 15:03:46 +0000 (+0000) Subject: fixed search with joins from related resultset X-Git-Tag: v0.07002~75^2~136 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=cd40c868c0783a1777774c47db16e8d1d1ff36e3;p=dbsrgits%2FDBIx-Class.git fixed search with joins from related resultset --- diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 759dec5..75e66a7 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -160,14 +160,17 @@ always return a resultset, even in list context. sub search_rs { my $self = shift; - my $our_attrs = { %{$self->{attrs}} }; - my $having = delete $our_attrs->{having}; my $attrs = {}; $attrs = pop(@_) if @_ > 1 and ref $_[$#_] eq 'HASH'; - + my $our_attrs = ($attrs->{_parent_attrs}) ? { %{$attrs->{_parent_attrs}} } : { %{$self->{attrs}} }; + my $having = delete $our_attrs->{having}; + # merge new attrs into old foreach my $key (qw/join prefetch/) { next unless (exists $attrs->{$key}); + if ($attrs->{_live_join} || $our_attrs->{_live_join}) { + $attrs->{$key} = { ($attrs->{_live_join}) ? $attrs->{_live_join} : $our_attrs->{_live_join} => $attrs->{$key} }; + } if (exists $our_attrs->{$key}) { $our_attrs->{$key} = $self->_merge_attr($our_attrs->{$key}, $attrs->{$key}); } else { @@ -176,13 +179,12 @@ sub search_rs { delete $attrs->{$key}; } + $our_attrs->{join} = $self->_merge_attr($our_attrs->{join}, $attrs->{_live_join}, 1) if ($attrs->{_live_join}); if (exists $our_attrs->{prefetch}) { $our_attrs->{join} = $self->_merge_attr($our_attrs->{join}, $our_attrs->{prefetch}, 1); } my $new_attrs = { %{$our_attrs}, %{$attrs} }; - - # merge new where and having into old my $where = (@_ ? ((@_ == 1 || ref $_[0] eq "HASH") ? shift @@ -670,7 +672,7 @@ sub _resolve { return if(exists $self->{_attrs}); #return if _resolve has already been called - my $attrs = $self->{attrs}; + my $attrs = $self->{attrs}; my $source = ($self->{_parent_rs}) ? $self->{_parent_rs} : $self->{result_source}; # XXX - lose storable dclone @@ -1563,15 +1565,15 @@ sub related_resultset { my $rs = $self->result_source->schema->resultset($rel_obj->{class} )->search( undef, - { %{$self->{attrs}}, - select => undef, + { select => undef, as => undef, - join => $rel, - _live_join => $rel } + #join => $rel, + _live_join => $rel, + _parent_attrs => $self->{attrs}} ); # keep reference of the original resultset - $rs->{_parent_rs} = $self->result_source; + $rs->{_parent_rs} = ($self->{_parent_rs}) ? $self->{_parent_rs} : $self->result_source; return $rs; }; } diff --git a/t/60core.t b/t/60core.t index 6ac90c7..a42d1ec 100644 --- a/t/60core.t +++ b/t/60core.t @@ -102,7 +102,7 @@ is($new_again->ID, 'DBICTest::Artist|artist|artistid=4', 'unique object id gener # Test backwards compatibility { - my $artist_by_hash = $schema->resultset('Artist')->find(artistid => 4); + my $artist_by_hash = $schema->resultset('Artist')->find({artistid => 4}); is($artist_by_hash->name, 'Man With A Spoon', 'Retrieved correctly'); is($artist_by_hash->ID, 'DBICTest::Artist|artist|artistid=4', 'unique object id generated correctly'); } diff --git a/t/90join_torture.t b/t/90join_torture.t index 532be1a..4a8aa4e 100644 --- a/t/90join_torture.t +++ b/t/90join_torture.t @@ -7,7 +7,7 @@ use DBICTest; my $schema = DBICTest->init_schema(); -plan tests => 8; +plan tests => 9; 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"); @@ -23,14 +23,12 @@ my @cds = $artists2[0]->cds; cmp_ok(scalar @cds, '==', 1, "condition based on inherited join okay"); # this is wrong, should accept me.title really -my $rs3 = $rs2->search_related('cds')->search({'cds.title' => 'Forkful of bees'}); - -cmp_ok($rs3->count, '==', 1, "Three artists returned"); +my $rs3 = $rs2->search_related('cds'); +cmp_ok($rs3->count, '==', 9, "Nine artists returned"); my $rs4 = $schema->resultset("CD")->search({ 'artist.artistid' => '1' }, { join => ['tracks', 'artist'], prefetch => 'artist' }); my @rs4_results = $rs4->all; - is($rs4_results[0]->cdid, 1, "correct artist returned"); my $rs5 = $rs4->search({'tracks.title' => 'Sticky Honey'}); @@ -44,4 +42,7 @@ 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 @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'); + 1; diff --git a/t/lib/DBICTest/Schema/Producer.pm b/t/lib/DBICTest/Schema/Producer.pm index 036f9f2..26e140e 100644 --- a/t/lib/DBICTest/Schema/Producer.pm +++ b/t/lib/DBICTest/Schema/Producer.pm @@ -17,4 +17,8 @@ __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;