From: Aran Deltac Date: Tue, 9 May 2006 22:02:44 +0000 (+0000) Subject: Add search_rs to ResultSet and a new {$rel}_rs accessor to has_many. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=5b89a7688c79c6b6109ee8ec5d43ee680bd8c22c;p=dbsrgits%2FDBIx-Class-Historic.git Add search_rs to ResultSet and a new {$rel}_rs accessor to has_many. --- diff --git a/Build.PL b/Build.PL index f1d2ad8..364a8d2 100644 --- a/Build.PL +++ b/Build.PL @@ -26,7 +26,8 @@ my %arguments = ( }, create_makefile_pl => 'passthrough', create_readme => 1, - test_files => [ glob('t/*.t'), glob('t/*/*.t') ] + test_files => [ glob('t/*.t'), glob('t/*/*.t') ], + script_files => [ glob('script/*') ], ); Module::Build->new(%arguments)->create_build_script; diff --git a/lib/DBIx/Class/Relationship.pm b/lib/DBIx/Class/Relationship.pm index 44ed65b..9e6d77d 100644 --- a/lib/DBIx/Class/Relationship.pm +++ b/lib/DBIx/Class/Relationship.pm @@ -131,6 +131,8 @@ of C. { prefetch => [qw/book/], }); my @book_objs = $obj->books; + my $books_rs = $obj->books; + ( $books_rs ) = $obj->books_rs; $obj->add_to_books(\%col_data); @@ -139,9 +141,14 @@ foreign class store the calling class's primary key in one (or more) of its columns. You should pass the name of the column in the foreign class as the $cond argument, or specify a complete join condition. -As well as the accessor method, a method named C<< add_to_ >> -will also be added to your Row items, this allows you to insert new -related items, using the same mechanism as in L. +Three methods are created when you create a has_many relationship. The first +method is the expected accessor method. The second is almost exactly the same +as the accessor method but "_rs" is added to the end of the method name. This +method works just like the normal accessor, except that it returns a resultset +no matter what, even in list context. The third method, named +C<< add_to_ >>, will also be added to your Row items, this allows +you to insert new related items, using the same mechanism as in +L. If you delete an object in a class with a C relationship, all related objects will be deleted as well. However, any database-level diff --git a/lib/DBIx/Class/Relationship/Accessor.pm b/lib/DBIx/Class/Relationship/Accessor.pm index 035661a..b20eb16 100644 --- a/lib/DBIx/Class/Relationship/Accessor.pm +++ b/lib/DBIx/Class/Relationship/Accessor.pm @@ -48,6 +48,7 @@ sub add_relationship_accessor { ); } elsif ($acc_type eq 'multi') { $meth{$rel} = sub { shift->search_related($rel, @_) }; + $meth{"${rel}_rs"} = sub { shift->search_related_rs($rel, @_) }; $meth{"add_to_${rel}"} = sub { shift->create_related($rel, @_); }; } else { $class->throw_exception("No such relationship accessor type $acc_type"); diff --git a/lib/DBIx/Class/Relationship/Base.pm b/lib/DBIx/Class/Relationship/Base.pm index b193aa0..9b1bde5 100644 --- a/lib/DBIx/Class/Relationship/Base.pm +++ b/lib/DBIx/Class/Relationship/Base.pm @@ -175,7 +175,8 @@ sub related_resultset { =head2 search_related - $rs->search_related('relname', $cond, $attrs); + @objects = $rs->search_related('relname', $cond, $attrs); + $objects_rs = $rs->search_related('relname', $cond, $attrs); Run a search on a related resultset. The search will be restricted to the item or items represented by the L it was called @@ -187,6 +188,19 @@ sub search_related { return shift->related_resultset(shift)->search(@_); } +=head2 search_related_rs + + ( $objects_rs ) = $rs->search_related_rs('relname', $cond, $attrs); + +This method works exactly the same as search_related_rs, except that +it garauntees that it will return a restultset even in list context. + +=cut + +sub search_related_rs { + return shift->related_resultset(shift)->search_rs(@_); +} + =head2 count_related $obj->count_related('relname', $cond, $attrs); diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index fa877a6..b8e0668 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -196,7 +196,28 @@ call it as C. sub search { my $self = shift; - + my $rs = $self->search_rs( @_ ); + return (wantarray ? $rs->all : $rs); +} + +=head2 search_rs + +=over 4 + +=item Arguments: $cond, \%attrs? + +=item Return Value: $resultset + +=back + +This method does the same exact thing as search() except it will +always return a resultset even in list context. + +=cut + +sub search_rs { + my $self = shift; + my $attrs = { %{$self->{attrs}} }; my $having = delete $attrs->{having}; $attrs = { %$attrs, %{ pop(@_) } } if @_ > 1 and ref $_[$#_] eq 'HASH'; @@ -234,7 +255,7 @@ sub search { } } - return (wantarray ? $rs->all : $rs); + return $rs; } =head2 search_literal diff --git a/t/run/01core.tl b/t/run/01core.tl index c1a5b46..58e9c93 100644 --- a/t/run/01core.tl +++ b/t/run/01core.tl @@ -158,7 +158,7 @@ is($schema->class("Artist")->field_name_for->{name}, 'artist name', 'mk_classdat my $search = [ { 'tags.tag' => 'Cheesy' }, { 'tags.tag' => 'Blue' } ]; -my $or_rs = $schema->resultset("CD")->search($search, { join => 'tags', +my( $or_rs ) = $schema->resultset("CD")->search_rs($search, { join => 'tags', order_by => 'cdid' }); cmp_ok($or_rs->count, '==', 5, 'Search with OR ok'); diff --git a/t/run/06relationship.tl b/t/run/06relationship.tl index b85fea1..a66211e 100644 --- a/t/run/06relationship.tl +++ b/t/run/06relationship.tl @@ -3,7 +3,7 @@ my $schema = shift; use strict; use warnings; -plan tests => 30; +plan tests => 32; # has_a test my $cd = $schema->resultset("CD")->find(4); @@ -38,6 +38,12 @@ if ($INC{'DBICTest/HelperRels.pm'}) { is( ($artist->search_related('cds'))[3]->title, 'Big Flop', 'create_related ok' ); +my( $rs_from_list ) = $artist->search_related_rs('cds'); +is( ref($rs_from_list), 'DBIx::Class::ResultSet', 'search_related_rs in list context returns rs' ); + +( $rs_from_list ) = $artist->cds_rs(); +is( ref($rs_from_list), 'DBIx::Class::ResultSet', 'relation_rs in list context returns rs' ); + # count_related is( $artist->count_related('cds'), 4, 'count_related ok' );