Skip to content

Commit

Permalink
Use a callback in findOrCreate instead of an array.
Browse files Browse the repository at this point in the history
Using a callback to set additional defaults gives more flexibility
and control to application developers around how to configure new
entities.
  • Loading branch information
markstory committed Sep 22, 2014
1 parent 162d8b3 commit 1f0eb1e
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 10 deletions.
12 changes: 8 additions & 4 deletions src/ORM/Table.php
Expand Up @@ -943,17 +943,21 @@ public function get($primaryKey, $options = []) {
* the $defaults. When a new entity is created, it will be saved.

This comment has been minimized.

Copy link
@ceeram

ceeram Sep 23, 2014

Contributor

$defaults parameter no longer exists

This comment has been minimized.

Copy link
@markstory

markstory Sep 23, 2014

Author Member

Thanks, I'll get that fixed.

*
* @param array $search The criteria to find existing records by.
* @param array $defaults The array of defaults to patch into
* the new entity if it is created.
* @param callable $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, $defaults = []) {
public function findOrCreate($search, callable $callback = null) {
$query = $this->find()->where($search);
$row = $query->first();
if ($row) {
return $row;
}
$entity = $this->newEntity($search + $defaults);
$entity = $this->newEntity($search);
if ($callback) {
$callback($entity);
}
return $this->save($entity);
}

Expand Down
17 changes: 11 additions & 6 deletions tests/TestCase/ORM/TableTest.php
Expand Up @@ -3531,29 +3531,34 @@ public function testDebugInfo() {
}

/**
* Test the findOrNew method.
* Test the findOrCreate method.
*
* @return void
*/
public function testFindOrNew() {
public function testFindOrCreate() {
$articles = TableRegistry::get('Articles');
$article = $articles->findOrCreate(['title' => 'Not there'], ['body' => 'New body']);
$article = $articles->findOrCreate(['title' => 'Not there'], function ($article) {
$article->body = 'New body';
});

$this->assertFalse($article->isNew());
$this->assertNotNull($article->id);
$this->assertEquals('Not there', $article->title);
$this->assertEquals('New body', $article->body);

$article = $articles->findOrCreate(['title' => 'First Article'], ['body' => 'New body']);
$article = $articles->findOrCreate(['title' => 'First Article'], function ($article) {
$this->fail('Should not be called for existing entities.');
});

$this->assertFalse($article->isNew());
$this->assertNotNull($article->id);
$this->assertEquals('First Article', $article->title);
$this->assertNotEquals('New body', $article->body);

$article = $articles->findOrCreate(
['author_id' => 2, 'title' => 'First Article'],
['published' => 'N', 'body' => 'New body']
function ($article) {
$article->set(['published' => 'N', 'body' => 'New body']);
}
);
$this->assertFalse($article->isNew());
$this->assertNotNull($article->id);
Expand Down

0 comments on commit 1f0eb1e

Please sign in to comment.