fixed search with joins from related resultset
Luke Saunders [Tue, 6 Jun 2006 15:03:46 +0000 (15:03 +0000)]
lib/DBIx/Class/ResultSet.pm
t/60core.t
t/90join_torture.t
t/lib/DBICTest/Schema/Producer.pm

index 759dec5..75e66a7 100644 (file)
@@ -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;
   };
 }
index 6ac90c7..a42d1ec 100644 (file)
@@ -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');
 }
index 532be1a..4a8aa4e 100644 (file)
@@ -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;
index 036f9f2..26e140e 100644 (file)
@@ -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;