No longer use rel_info($rel)->{class} in the cond resolver
Peter Rabbitson [Sun, 7 Sep 2014 11:20:18 +0000 (13:20 +0200)]
It turns out there are a lot of codebases there containing garbage in the
rel definition. Punt for after 0.082800 to lean up that mess.

Also be less strict on checking the foreign_values contents - downgrade
mismatches to a warning (but still hard-require ::Row ancestry)

lib/DBIx/Class/ResultSource.pm
t/cdbi/06-hasa.t
t/cdbi/18-has_a.t

index d046875..6baff16 100644 (file)
@@ -1835,7 +1835,7 @@ Internals::SvREADONLY($UNRESOLVABLE_CONDITION => 1);
 ## self-explanatory API, modeled on the custom cond coderef:
 # rel_name              => (scalar)
 # foreign_alias         => (scalar)
-# foreign_values        => (either not supplied or a hashref)
+# foreign_values        => (either not supplied, or a hashref, or a foreign ResultObject (to be ->get_columns()ed), or plain undef )
 # self_alias            => (scalar)
 # self_result_object    => (either not supplied or a result object)
 # require_join_free_condition => (boolean, throws on failure to construct a JF-cond)
@@ -1893,8 +1893,15 @@ sub _resolve_relationship_condition {
 
   if (exists $args->{foreign_values}) {
     if (defined blessed $args->{foreign_values}) {
-      $self->throw_exception( "Object supplied as 'foreign_values' ($args->{foreign_values}) must be of class '$rel_info->{class}'" )
-        unless $args->{foreign_values}->isa($rel_info->{class});
+
+      $self->throw_exception( "Objects supplied as 'foreign_values' ($args->{foreign_values}) must inherit from DBIx::Class::Row" )
+        unless $args->{foreign_values}->isa('DBIx::Class::Row');
+
+      carp_unique(
+        "Objects supplied as 'foreign_values' ($args->{foreign_values}) "
+      . "usually should inherit from the related ResultClass ('@{[ $rel_rsrc->result_class ]}'), "
+      . "perhaps you've made a mistake invoking the condition resolver?"
+      ) unless $args->{foreign_values}->isa($rel_rsrc->result_class);
 
       $args->{foreign_values} = { $args->{foreign_values}->get_columns };
     }
@@ -1905,7 +1912,10 @@ sub _resolve_relationship_condition {
       ) for keys %{ $args->{foreign_values} ||= {} };
     }
     else {
-      $self->throw_exception( "Argument 'foreign_values' must be either an object inheriting from '$rel_info->{class}' or a hash reference or undef" );
+      $self->throw_exception(
+        "Argument 'foreign_values' must be either an object inheriting from '@{[ $rel_rsrc->result_class ]}', "
+      . "or a hash reference, or undef"
+      );
     }
   }
 
index 255383b..02933cd 100644 (file)
@@ -1,6 +1,8 @@
 use strict;
 use warnings;
 use Test::More;
+use Test::Exception;
+use DBIx::Class::_Util 'sigwarn_silencer';
 
 @YA::Film::ISA = 'Film';
 
@@ -105,7 +107,8 @@ sub taste_bad {
 
 sub fail_with_bad_object {
   my ($dir, $codir) = @_;
-  eval {
+  throws_ok {
+    local $SIG{__WARN__} = sigwarn_silencer( qr/\Qusually should inherit from the related ResultClass ('Director')/ );
     YA::Film->create(
       {
         Title             => 'Tastes Bad',
@@ -115,8 +118,7 @@ sub fail_with_bad_object {
         NumExplodingSheep => 23
       }
     );
-  };
-  ok $@, $@;
+  } qr/isn't a Director/;
 }
 
 package Foo;
index 1dacd6c..e1deb09 100644 (file)
@@ -1,6 +1,8 @@
 use strict;
 use warnings;
 use Test::More;
+use Test::Exception;
+use DBIx::Class::_Util 'sigwarn_silencer';
 
 use lib 't/cdbi/testlib';
 use Film;
@@ -45,8 +47,8 @@ my $sj = Director->create({
   });
 
 {
-  eval { $btaste->Director($btaste) };
-  like $@, qr/Director/, "Can't set film as director";
+  throws_ok { $btaste->Director($btaste) }
+    qr/isn't a Director/, "Can't set film as director";
   is $btaste->Director->id, $pj->id, "PJ still the director";
 
   # drop from cache so that next retrieve() is from db
@@ -69,8 +71,7 @@ my $sj = Director->create({
 is $sj->id, 'Skippy Jackson', 'Create new director - Skippy';
 Film->has_a('CoDirector' => 'Director');
 {
-  eval { $btaste->CoDirector("Skippy Jackson") };
-  is $@, "", "Auto inflates";
+  lives_ok { $btaste->CoDirector("Skippy Jackson") };
   isa_ok $btaste->CoDirector, "Director";
   is $btaste->CoDirector->id, $sj->id, "To skippy";
 }
@@ -96,7 +97,8 @@ is(
   $pj = Director->retrieve('Peter Jackson');
 
   my $fail;
-  eval {
+  throws_ok {
+    local $SIG{__WARN__} = sigwarn_silencer( qr/\Qusually should inherit from the related ResultClass ('Director')/ );
     $fail = YA::Film->create({
         Title             => 'Tastes Bad',
         Director          => $sj,
@@ -104,8 +106,7 @@ is(
         Rating            => 'R',
         NumExplodingSheep => 23
       });
-  };
-  ok $@,    "Can't have film as codirector: $@";
+  } qr/isn't a Director/, "Can't have film as codirector";
   is $fail, undef, "We didn't get anything";
 
   my $tastes_bad = YA::Film->create({
@@ -226,8 +227,10 @@ SKIP: {
 }
 
 { # Broken has_a declaration
-  eval { Film->has_a(driector => "Director") };
-  like $@, qr/driector/, "Sensible error from has_a with incorrect column: $@";
+  throws_ok{ Film->has_a(driector => "Director") }
+    qr/No such column driector/,
+    "Sensible error from has_a with incorrect column"
+  ;
 }
 
 done_testing;