From 1f0eb1e800a72d06d64670e48b6fd637cb191f3e Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 21 Sep 2014 20:24:40 -0400 Subject: [PATCH] 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. --- src/ORM/Table.php | 12 ++++++++---- tests/TestCase/ORM/TableTest.php | 17 +++++++++++------ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/ORM/Table.php b/src/ORM/Table.php index 560422dd939..bf1ec3adb32 100644 --- a/src/ORM/Table.php +++ b/src/ORM/Table.php @@ -943,17 +943,21 @@ public function get($primaryKey, $options = []) { * the $defaults. When a new entity is created, it will be saved. * * @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); } diff --git a/tests/TestCase/ORM/TableTest.php b/tests/TestCase/ORM/TableTest.php index aa297f518b3..7321b59ef00 100644 --- a/tests/TestCase/ORM/TableTest.php +++ b/tests/TestCase/ORM/TableTest.php @@ -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);