Skip to content

Commit

Permalink
Check relationship declarations more consistently
Browse files Browse the repository at this point in the history
  • Loading branch information
ribasushi committed Jul 29, 2014
1 parent 1016d16 commit 6909ab3
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 5 deletions.
1 change: 1 addition & 0 deletions Changes
Expand Up @@ -30,6 +30,7 @@ Revision history for DBIx::Class
mode of a has_many prefetch off a search_related chain
- Prevent erroneous database hit when accessing prefetched related
resultsets with no rows
- Proper exceptions on malformed relationship conditions (RT#92234)
- Fix incorrect handling of custom relationship conditions returning
SQLA literal expressions
- Fix long standing bug with populate() missing data from hashrefs with
Expand Down
2 changes: 2 additions & 0 deletions lib/DBIx/Class/Relationship/BelongsTo.pm
Expand Up @@ -60,6 +60,8 @@ sub belongs_to {
else {
if (ref $cond eq 'HASH') { # ARRAY is also valid
my $cond_rel;
# FIXME This loop is ridiculously incomplete and dangerous
# staving off changes until implmentation of the swindon consensus
for (keys %$cond) {
if (m/\./) { # Explicit join condition
$cond_rel = $cond;
Expand Down
3 changes: 2 additions & 1 deletion lib/DBIx/Class/Relationship/HasOne.pm
Expand Up @@ -91,8 +91,9 @@ sub _validate_has_one_condition {
my $self_id = $cond->{$foreign_id};

# we can ignore a bad $self_id because add_relationship handles this
# warning
# exception
return unless $self_id =~ /^self\.(.*)$/;

my $key = $1;
$class->throw_exception("Defining rel on ${class} that includes '$key' but no such column defined here yet")
unless $class->has_column($key);
Expand Down
9 changes: 5 additions & 4 deletions lib/DBIx/Class/ResultSource.pm
Expand Up @@ -1320,10 +1320,11 @@ sub add_relationship {

# Check foreign and self are right in cond
if ( (ref $cond ||'') eq 'HASH') {
for (keys %$cond) {
$self->throw_exception("Keys of condition should be of form 'foreign.col', not '$_'")
if /\./ && !/^foreign\./;
}
$_ =~ /^foreign\./ or $self->throw_exception("Malformed relationship condition key '$_': must be prefixed with 'foreign.'")
for keys %$cond;

$_ =~ /^self\./ or $self->throw_exception("Malformed relationship condition value '$_': must be prefixed with 'self.'")
for values %$cond;
}

my %rels = %{ $self->_relationships };
Expand Down
28 changes: 28 additions & 0 deletions t/relationship/malformed_declaration.t
@@ -0,0 +1,28 @@
use strict;
use warnings;

use Test::More;
use Test::Exception;
use lib qw(t/lib);
use DBICTest::Schema::Artist;

my $pkg = 'DBICTest::Schema::Artist';

for my $call (qw(has_many might_have has_one belongs_to)) {
{
local $TODO = 'stupid stupid heuristic - needs to die'
if $call eq 'belongs_to';

throws_ok {
$pkg->$call( foos => 'nonexistent bars', { foo => 'self.artistid' } );
} qr/Malformed relationship condition key 'foo': must be prefixed with 'foreign.'/,
"Correct exception on $call with malformed foreign.";
}

throws_ok {
$pkg->has_many( foos => 'nonexistent bars', { 'foreign.foo' => 'name' } );
} qr/\QMalformed relationship condition value 'name': must be prefixed with 'self.'/,
"Correct exception on $call with malformed self.";
}

done_testing;

0 comments on commit 6909ab3

Please sign in to comment.