Change once more the signature of the custom cond coderef (augment a446d7f8)
[dbsrgits/DBIx-Class-Historic.git] / lib / DBIx / Class / Relationship / Base.pm
index e2f6224..42d0955 100644 (file)
@@ -184,7 +184,7 @@ While every coderef-based condition must return a valid C<ON> clause, it may
 elect to additionally return a simplified join-free condition hashref when
 invoked as C<< $result->relationship >>, as opposed to
 C<< $rs->related_resultset('relationship') >>. In this case C<$result> is
-passed to the coderef as C<< $args->{self_resultobj} >>, so a user can do the
+passed to the coderef as C<< $args->{self_result_object} >>, so a user can do the
 following:
 
   sub {
@@ -195,8 +195,8 @@ following:
         "$args->{foreign_alias}.artist" => { -ident => "$args->{self_alias}.artistid" },
         "$args->{foreign_alias}.year"   => { '>', "1979", '<', "1990" },
       },
-      $args->{self_resultobj} && {
-        "$args->{foreign_alias}.artist" => $args->{self_resultobj}->artistid,
+      $args->{self_result_object} && {
+        "$args->{foreign_alias}.artist" => $args->{self_result_object}->artistid,
         "$args->{foreign_alias}.year"   => { '>', "1979", '<', "1990" },
       },
     );
@@ -233,20 +233,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_resultsource => The resultsource instance on which rel_name is registered
-    rel_name          => The relationship name (does *NOT* always match foreign_alias)
+    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)
+    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)
+    self_result_object    => The invocant object itself in case of a $result_object->$rel_name( ... ) call
+    foreign_result_object => The related object in case of $result_object->set_from_related( $rel_name, $foreign_result_object )
 
     # 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
+    self_rowobj           => Old deprecated slot for self_result_object
+    foreign_relname       => Old deprecated slot for rel_name
   });
 
 =head3 attributes
@@ -475,7 +475,9 @@ sub related_resultset {
 
   return $self->{related_resultsets}{$rel} = do {
 
-    my $rel_info = $self->relationship_info($rel)
+    my $rsrc = $self->result_source;
+
+    my $rel_info = $rsrc->relationship_info($rel)
       or $self->throw_exception( "No such relationship '$rel'" );
 
     my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
@@ -485,8 +487,6 @@ sub related_resultset {
       if (@_ > 1 && (@_ % 2 == 1));
     my $query = ((@_ > 1) ? {@_} : shift);
 
-    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 {
@@ -631,42 +631,15 @@ your storage until you call L<DBIx::Class::Row/insert> on it.
 =cut
 
 sub new_related {
-  my ($self, $rel, $values) = @_;
-
-  # FIXME - this is a bad position for this (also an identical copy in
-  # set_from_related), but I have no saner way to hook, and I absolutely
-  # want this to throw at least for coderefs, instead of the "insert a NULL
-  # when it gets hard" insanity --ribasushi
-  #
-  # sanity check - currently throw when a complex coderef rel is encountered
-  # FIXME - should THROW MOAR!
-
-  if (ref $self) {  # cdbi calls this as a class method, /me vomits
-
-    my $rsrc = $self->result_source;
-    my $rel_info = $rsrc->relationship_info($rel)
-      or $self->throw_exception( "No such relationship '$rel'" );
-    my (undef, $crosstable, $nonequality_foreign_columns) = $rsrc->_resolve_condition (
-      $rel_info->{cond}, $rel, $self, $rel
-    );
-
-    $self->throw_exception("Relationship '$rel' does not resolve to a join-free condition fragment")
-      if $crosstable;
-
-    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,
-        map { "'$_'" } @unspecified_rel_condition_chunks
-      ));
-    }
-  }
-
-  return $self->search_related($rel)->new_result($values);
+  my ($self, $rel, $data) = @_;
+
+  return $self->search_related($rel)->new_result( $self->result_source->_resolve_relationship_condition (
+    infer_values_based_on => $data,
+    rel_name => $rel,
+    self_result_object => $self,
+    foreign_alias => $rel,
+    self_alias => 'me',
+  )->{inferred_values} );
 }
 
 =head2 create_related
@@ -808,37 +781,13 @@ set them in the storage.
 sub set_from_related {
   my ($self, $rel, $f_obj) = @_;
 
-  my $rsrc = $self->result_source;
-  my $rel_info = $rsrc->relationship_info($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 )
-      unless blessed $f_obj and $f_obj->isa($f_class);
-  }
-
-
-  # FIXME - this is a bad position for this (also an identical copy in
-  # new_related), but I have no saner way to hook, and I absolutely
-  # want this to throw at least for coderefs, instead of the "insert a NULL
-  # when it gets hard" insanity --ribasushi
-  #
-  # sanity check - currently throw when a complex coderef rel is encountered
-  # FIXME - should THROW MOAR!
-  my ($cond, $crosstable, $nonequality_foreign_columns) = $rsrc->_resolve_condition (
-    $rel_info->{cond}, $f_obj, $rel, $rel
-  );
-  $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 { "'$_'" } @$nonequality_foreign_columns
-  )) if $nonequality_foreign_columns;
-
-  $self->set_columns($cond);
+  $self->set_columns( $self->result_source->_resolve_relationship_condition (
+    infer_values_based_on => {},
+    rel_name => $rel,
+    foreign_result_object => $f_obj,
+    foreign_alias => $rel,
+    self_alias => 'me',
+  )->{inferred_values} );
 
   return 1;
 }