Skip to content

Commit 1f0eb1e

Browse files
committed
Use a callback in findOrCreate instead of an array.
Using a callback to set additional defaults gives more flexibility and control to application developers around how to configure new entities.
1 parent 162d8b3 commit 1f0eb1e

File tree

2 files changed

+19
-10
lines changed

2 files changed

+19
-10
lines changed

src/ORM/Table.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -943,17 +943,21 @@ public function get($primaryKey, $options = []) {
943943
* the $defaults. When a new entity is created, it will be saved.
944944
*
945945
* @param array $search The criteria to find existing records by.
946-
* @param array $defaults The array of defaults to patch into
947-
* the new entity if it is created.
946+
* @param callable $callback A callback that will be invoked for newly
947+
* created entities. This callback will be called *before* the entity
948+
* is persisted.
948949
* @return \Cake\Datasource\EntityInterface An entity.
949950
*/
950-
public function findOrCreate($search, $defaults = []) {
951+
public function findOrCreate($search, callable $callback = null) {
951952
$query = $this->find()->where($search);
952953
$row = $query->first();
953954
if ($row) {
954955
return $row;
955956
}
956-
$entity = $this->newEntity($search + $defaults);
957+
$entity = $this->newEntity($search);
958+
if ($callback) {
959+
$callback($entity);
960+
}
957961
return $this->save($entity);
958962
}
959963

tests/TestCase/ORM/TableTest.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3531,29 +3531,34 @@ public function testDebugInfo() {
35313531
}
35323532

35333533
/**
3534-
* Test the findOrNew method.
3534+
* Test the findOrCreate method.
35353535
*
35363536
* @return void
35373537
*/
3538-
public function testFindOrNew() {
3538+
public function testFindOrCreate() {
35393539
$articles = TableRegistry::get('Articles');
3540-
$article = $articles->findOrCreate(['title' => 'Not there'], ['body' => 'New body']);
3540+
$article = $articles->findOrCreate(['title' => 'Not there'], function ($article) {
3541+
$article->body = 'New body';
3542+
});
35413543

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

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

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

35543557
$article = $articles->findOrCreate(
35553558
['author_id' => 2, 'title' => 'First Article'],
3556-
['published' => 'N', 'body' => 'New body']
3559+
function ($article) {
3560+
$article->set(['published' => 'N', 'body' => 'New body']);
3561+
}
35573562
);
35583563
$this->assertFalse($article->isNew());
35593564
$this->assertNotNull($article->id);

0 commit comments

Comments
 (0)