X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FRelationship%2FBase.pm;h=6dcfc6781313ae32a52891ee880d8d15da5506c8;hb=3b4c4d727a91b9091efe2b3a34193b9abf14313f;hp=feabdc7c5a39179998fd9b26c2db8b569e5b2ad3;hpb=69bc5f2b82b4a4f027cd9d57c38c25dc4e0b72c0;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Relationship/Base.pm b/lib/DBIx/Class/Relationship/Base.pm index feabdc7..6dcfc67 100644 --- a/lib/DBIx/Class/Relationship/Base.pm +++ b/lib/DBIx/Class/Relationship/Base.pm @@ -428,7 +428,7 @@ $rel_name. $rs = $cd->related_resultset('tracks'); # has_many relationship $rs = $cd->tracks; -This is the recommended way to transverse through relationships, based +This is the recommended way to traverse through relationships, based on the L name given in the relationship definition. This will return either a L or a @@ -441,14 +441,17 @@ this instance (like in the case of C relationships). sub related_resultset { my $self = shift; + $self->throw_exception("Can't call *_related as class methods") unless ref $self; + my $rel = shift; - my $rel_info = $self->relationship_info($rel); - $self->throw_exception( "No such relationship ${rel}" ) - unless $rel_info; return $self->{related_resultsets}{$rel} ||= do { + + my $rel_info = $self->relationship_info($rel) + or $self->throw_exception( "No such relationship '$rel'" ); + my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {}); $attrs = { %{$rel_info->{attrs} || {}}, %$attrs }; @@ -456,12 +459,12 @@ sub related_resultset { if (@_ > 1 && (@_ % 2 == 1)); my $query = ((@_ > 1) ? {@_} : shift); - my $source = $self->result_source; + my $rsrc = $self->result_source; # condition resolution may fail if an incomplete master-object prefetch # is encountered - that is ok during prefetch construction (not yet in_storage) my ($cond, $is_crosstable) = try { - $source->_resolve_condition( $rel_info->{cond}, $rel, $self, $rel ) + $rsrc->_resolve_condition( $rel_info->{cond}, $rel, $self, $rel ) } catch { if ($self->in_storage) { @@ -474,8 +477,8 @@ sub related_resultset { # keep in mind that the following if() block is part of a do{} - no return()s!!! if ($is_crosstable) { $self->throw_exception ( - "A cross-table relationship condition returned for statically declared '$rel'") - unless ref $rel_info->{cond} eq 'CODE'; + "A cross-table relationship condition returned for statically declared '$rel'" + ) unless ref $rel_info->{cond} eq 'CODE'; # A WHOREIFFIC hack to reinvoke the entire condition resolution # with the correct alias. Another way of doing this involves a @@ -487,11 +490,11 @@ sub related_resultset { # root alias as 'me', instead of $rel (as opposed to invoking # $rs->search_related) - local $source->{_relationships}{me} = $source->{_relationships}{$rel}; # make the fake 'me' rel - my $obj_table_alias = lc($source->source_name) . '__row'; + local $rsrc->{_relationships}{me} = $rsrc->{_relationships}{$rel}; # make the fake 'me' rel + my $obj_table_alias = lc($rsrc->source_name) . '__row'; $obj_table_alias =~ s/\W+/_/g; - $source->resultset->search( + $rsrc->resultset->search( $self->ident_condition($obj_table_alias), { alias => $obj_table_alias }, )->search_related('me', $query, $attrs) @@ -501,7 +504,7 @@ sub related_resultset { # at some point what it does. Also the entire UNRESOLVABLE_CONDITION # business seems shady - we could simply not query *at all* if ($cond eq $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION) { - my $reverse = $source->reverse_relationship_info($rel); + my $reverse = $rsrc->reverse_relationship_info($rel); foreach my $rev_rel (keys %$reverse) { if ($reverse->{$rev_rel}{attrs}{accessor} && $reverse->{$rev_rel}{attrs}{accessor} eq 'multi') { weaken($attrs->{related_objects}{$rev_rel}[0] = $self); @@ -531,7 +534,7 @@ sub related_resultset { } $query = ($query ? { '-and' => [ $cond, $query ] } : $cond); - $self->result_source->related_source($rel)->resultset->search( + $rsrc->related_source($rel)->resultset->search( $query, $attrs ); } @@ -587,8 +590,7 @@ current result or where conditions. =cut sub count_related { - my $self = shift; - return $self->search_related(@_)->count; + shift->search_related(@_)->count; } =head2 new_related @@ -622,18 +624,18 @@ sub new_related { if (ref $self) { # cdbi calls this as a class method, /me vomits my $rsrc = $self->result_source; - my (undef, $crosstable, $relcols) = $rsrc->_resolve_condition ( + my (undef, $crosstable, $cond_targets) = $rsrc->_resolve_condition ( $rsrc->relationship_info($rel)->{cond}, $rel, $self, $rel ); $self->throw_exception("Custom relationship '$rel' does not resolve to a join-free condition fragment") if $crosstable; - if (@{$relcols || []} and @$relcols = grep { ! exists $values->{$_} } @$relcols) { + if (my @unspecified_rel_condition_chunks = grep { ! exists $values->{$_} } @{$cond_targets||[]} ) { $self->throw_exception(sprintf ( "Custom relationship '%s' not definitive - returns conditions instead of values for column(s): %s", $rel, - map { "'$_'" } @$relcols + map { "'$_'" } @unspecified_rel_condition_chunks )); } } @@ -685,9 +687,8 @@ See L for details. =cut sub find_related { - my $self = shift; - my $rel = shift; - return $self->search_related($rel)->find(@_); + #my ($self, $rel, @args) = @_; + return shift->search_related(shift)->find(@_); } =head2 find_or_new_related @@ -748,9 +749,8 @@ L for details. =cut sub update_or_create_related { - my $self = shift; - my $rel = shift; - return $self->related_resultset($rel)->update_or_create(@_); + #my ($self, $rel, @args) = @_; + shift->related_resultset(shift)->update_or_create(@_); } =head2 set_from_related @@ -784,11 +784,11 @@ sub set_from_related { my $rsrc = $self->result_source; my $rel_info = $rsrc->relationship_info($rel) - or $self->throw_exception( "No such relationship ${rel}" ); + or $self->throw_exception( "No such relationship '$rel'" ); if (defined $f_obj) { my $f_class = $rel_info->{class}; - $self->throw_exception( "Object $f_obj isn't a ".$f_class ) + $self->throw_exception( "Object '$f_obj' isn't a ".$f_class ) unless blessed $f_obj and $f_obj->isa($f_class); } @@ -800,7 +800,7 @@ sub set_from_related { # # sanity check - currently throw when a complex coderef rel is encountered # FIXME - should THROW MOAR! - my ($cond, $crosstable, $relcols) = $rsrc->_resolve_condition ( + my ($cond, $crosstable, $cond_targets) = $rsrc->_resolve_condition ( $rel_info->{cond}, $f_obj, $rel, $rel ); $self->throw_exception("Custom relationship '$rel' does not resolve to a join-free condition fragment") @@ -808,8 +808,8 @@ sub set_from_related { $self->throw_exception(sprintf ( "Custom relationship '%s' not definitive - returns conditions instead of values for column(s): %s", $rel, - map { "'$_'" } @$relcols - )) if @{$relcols || []}; + map { "'$_'" } @$cond_targets + )) if $cond_targets; $self->set_columns($cond);