Skip to content

Commit

Permalink
Initial implementation of Query::notMatching()
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Jun 6, 2015
1 parent bd0f737 commit 2d35e45
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 2 deletions.
10 changes: 9 additions & 1 deletion src/ORM/Association.php
Expand Up @@ -499,6 +499,14 @@ public function attachTo(Query $query, array $options = [])
}
}

if ($options['negateMatch']) {
$primaryKey = $query->aliasFields((array)$target->primaryKey(), $this->_name);
$query->andWhere(function ($exp) use ($primaryKey) {
array_map([$exp, 'isNull'], $primaryKey);
return $exp;
});
}

list($finder, $opts) = $this->_extractFinder($options['finder']);
$dummy = $this
->find($finder, $opts)
Expand All @@ -518,7 +526,7 @@ public function attachTo(Query $query, array $options = [])

$joinOptions = ['table' => 1, 'conditions' => 1, 'type' => 1];
$options['conditions'] = $dummy->clause('where');
$query->join([$target->alias() => array_intersect_key($options, $joinOptions)]);
$query->join([$this->_name => array_intersect_key($options, $joinOptions)]);

$this->_appendFields($query, $dummy, $options);
$this->_formatAssociationResults($query, $dummy, $options);
Expand Down
3 changes: 2 additions & 1 deletion src/ORM/EagerLoader.php
Expand Up @@ -64,7 +64,8 @@ class EagerLoader
'queryBuilder' => 1,
'finder' => 1,
'joinType' => 1,
'strategy' => 1
'strategy' => 1,
'negateMatch' => 1
];

/**
Expand Down
11 changes: 11 additions & 0 deletions src/ORM/Query.php
Expand Up @@ -455,6 +455,17 @@ public function innerJoinWith($assoc, callable $builder = null)
return $this;
}

public function notMatching($assoc, callable $builder = null)
{
$this->eagerLoader()->matching($assoc, $builder, [
'joinType' => 'LEFT',
'fields' => false,
'negateMatch' => true
]);
$this->_dirty();
return $this;
}

/**
* Returns a key => value array representing a single aliased field
* that can be passed directly to the select() method.
Expand Down
30 changes: 30 additions & 0 deletions tests/TestCase/ORM/QueryTest.php
Expand Up @@ -2844,4 +2844,34 @@ public function testInnerJoinWithSelect()
->toArray();
$this->assertEquals($expected, $results);
}

public function testNotMatching()
{
$table = TableRegistry::get('authors');
$articles = $table->hasMany('articles');

$results = $table->find()
->hydrate(false)
->notMatching('articles')
->toArray();

$expected = [
['id' => 2, 'name' => 'nate'],
['id' => 4, 'name' => 'garrett'],
];
$this->assertEquals($expected, $results);

$results = $table->find()
->hydrate(false)
->notMatching('articles', function ($q) {
return $q->where(['articles.author_id' => 1]);
})
->toArray();
$expected = [
['id' => 2, 'name' => 'nate'],
['id' => 3, 'name' => 'larry'],
['id' => 4, 'name' => 'garrett'],
];
$this->assertEquals($expected, $results);
}
}

0 comments on commit 2d35e45

Please sign in to comment.