Skip to content

Commit

Permalink
#8671 Improving Table::findOrCreate()
Browse files Browse the repository at this point in the history
  • Loading branch information
Florian Krämer committed Apr 21, 2016
1 parent 623e662 commit 7c104a9
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
23 changes: 21 additions & 2 deletions src/ORM/Table.php
Expand Up @@ -1213,15 +1213,15 @@ public function get($primaryKey, $options = [])
* called allowing you to define additional default values. The new
* entity will be saved and returned.
*
* @param array $search The criteria to find existing records by.
* @param array|\Cake\ORM\Query|string $search The criteria to find existing records by.
* @param callable|null $callback A callback that will be invoked for newly
* created entities. This callback will be called *before* the entity
* is persisted.
* @return \Cake\Datasource\EntityInterface An entity.
*/
public function findOrCreate($search, callable $callback = null)
{
$query = $this->find()->where($search);
$query = $this->_getFindOrCreateQuery($search);
$row = $query->first();
if ($row) {
return $row;
Expand All @@ -1234,6 +1234,25 @@ public function findOrCreate($search, callable $callback = null)
return $this->save($entity) ?: $entity;
}

/**
* Gets the query object for findOrCreate().
*
* @param array|\Cake\ORM\Query|string $search The criteria to find existing records by.
* @return \Cake\ORM\Query
*/
protected function _getFindOrCreateQuery($search) {
if ($search instanceof Query) {
return $search;
} elseif (is_string($search)) {
if (method_exists($this, $search)) {
return $this->{$search}();
} else {
throw new InvalidArgumentException('Method `' . $search . '` does not exist!');
}
}
return $this->find()->where($search);
}

/**
* {@inheritDoc}
*/
Expand Down
16 changes: 16 additions & 0 deletions tests/TestCase/ORM/TableTest.php
Expand Up @@ -5383,6 +5383,22 @@ function ($article) {
$this->assertEquals('New body', $article->body);
$this->assertEquals('N', $article->published);
$this->assertEquals(2, $article->author_id);

$query = $articles->find()->where(['author_id' => 2, 'title' => 'First Article']);
$article = $articles->findOrCreate($query);
$this->assertEquals('First Article', $article->title);
$this->assertEquals(2, $article->author_id);
}

/**
* Test that exceptions from the findOrCreate are thrown.
*
* @expectedException \InvalidArgumentException
*/
public function testFindOrCreateException()
{
$articles = TableRegistry::get('Articles');
$articles->findOrCreate('doesNotExist');
}

/**
Expand Down

0 comments on commit 7c104a9

Please sign in to comment.