Add foreign_resultobj to the customrel signature
[dbsrgits/DBIx-Class-Historic.git] / lib / DBIx / Class / Relationship / Base.pm
index a41d6b4..e11263f 100644 (file)
@@ -38,11 +38,11 @@ methods, for predefined ones, look in L<DBIx::Class::Relationship>.
 
 =over 4
 
-=item Arguments: 'relname', 'Foreign::Class', $condition, $attrs
+=item Arguments: $rel_name, $foreign_class, $condition, $attrs
 
 =back
 
-  __PACKAGE__->add_relationship('relname',
+  __PACKAGE__->add_relationship('rel_name',
                                 'Foreign::Class',
                                 $condition, $attrs);
 
@@ -232,11 +232,20 @@ clause, the C<$args> hashref passed to the subroutine contains some extra
 metadata. Currently the supplied coderef is executed as:
 
   $relationship_info->{cond}->({
-    self_alias        => The alias of the invoking resultset ('me' in case of a result object),
-    foreign_alias     => The alias of the to-be-joined resultset (often matches relname),
-    self_resultsource => The invocant's resultsource,
-    foreign_relname   => The relationship name (does *not* always match foreign_alias),
-    self_rowobj       => The invocant itself in case of a $result_object->$relationship call
+    self_resultsource => The resultsource instance on which rel_name is registered
+    rel_name          => The relationship name (does *NOT* always match foreign_alias)
+
+    self_alias        => The alias of the invoking resultset
+    foreign_alias     => The alias of the to-be-joined resultset (does *NOT* always match rel_name)
+
+    # only one of these (or none at all) will ever be supplied to aid in the
+    # construction of a join-free condition
+    self_resultobj    => The invocant object itself in case of a $resultobj->$rel_name() call
+    foreign_resultobj => The related object in case of $resultobj->set_from_related($rel_name, $foreign_resultobj)
+
+    # deprecated inconsistent names, will be forever available for legacy code
+    self_rowobj       => Old deprecated slot for self_resultobj
+    foreign_relname   => Old deprecated slot for rel_name
   });
 
 =head3 attributes
@@ -483,18 +492,12 @@ sub related_resultset {
       $rsrc->_resolve_condition( $rel_info->{cond}, $rel, $self, $rel )
     }
     catch {
-      if ($self->in_storage) {
-        $self->throw_exception ($_);
-      }
-
-      $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION;  # RV
+      $self->throw_exception ($_) if $self->in_storage;
+      $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION;  # RV, no return()
     };
 
     # 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';
+    if ($is_crosstable and 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
@@ -642,14 +645,18 @@ sub new_related {
     my $rsrc = $self->result_source;
     my $rel_info = $rsrc->relationship_info($rel)
       or $self->throw_exception( "No such relationship '$rel'" );
-    my (undef, $crosstable, $cond_targets) = $rsrc->_resolve_condition (
+    my (undef, $crosstable, $nonequality_foreign_columns) = $rsrc->_resolve_condition (
       $rel_info->{cond}, $rel, $self, $rel
     );
 
-    $self->throw_exception("Custom relationship '$rel' does not resolve to a join-free condition fragment")
+    $self->throw_exception("Relationship '$rel' does not resolve to a join-free condition fragment")
       if $crosstable;
 
-    if (my @unspecified_rel_condition_chunks = grep { ! exists $values->{$_} } @{$cond_targets||[]} ) {
+    if (
+      $nonequality_foreign_columns
+        and
+      my @unspecified_rel_condition_chunks = grep { ! exists $values->{$_} } @$nonequality_foreign_columns
+    ) {
       $self->throw_exception(sprintf (
         "Custom relationship '%s' not definitive - returns conditions instead of values for column(s): %s",
         $rel,
@@ -818,16 +825,17 @@ sub set_from_related {
   #
   # sanity check - currently throw when a complex coderef rel is encountered
   # FIXME - should THROW MOAR!
-  my ($cond, $crosstable, $cond_targets) = $rsrc->_resolve_condition (
+  my ($cond, $crosstable, $nonequality_foreign_columns) = $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")
+  $self->throw_exception("Relationship '$rel' does not resolve to a join-free condition fragment")
     if $crosstable;
+
   $self->throw_exception(sprintf (
     "Custom relationship '%s' not definitive - returns conditions instead of values for column(s): %s",
     $rel,
-    map { "'$_'" } @$cond_targets
-  )) if $cond_targets;
+    map { "'$_'" } @$nonequality_foreign_columns
+  )) if $nonequality_foreign_columns;
 
   $self->set_columns($cond);