Browse Source

Merge pull request #5305 from cakephp/orm-findorfail

Add Query::firstOrFail()
José Lorenzo Rodríguez 11 years ago
parent
commit
784c15df09

+ 1 - 0
config/bootstrap.php

@@ -19,6 +19,7 @@ define('TIME_START', microtime(true));
 class_alias('Cake\Error\Debugger', 'Cake\Utility\Debugger');
 class_alias('Cake\Core\Configure\Engine\PhpConfig', 'Cake\Configure\Engine\PhpConfig');
 class_alias('Cake\Core\Configure\Engine\IniConfig', 'Cake\Configure\Engine\IniConfig');
+class_alias('Cake\Datasource\Exception\RecordNotFoundException', 'Cake\ORM\Exception\RecordNotFoundException');
 class_alias('Cake\ORM\Exception\RecordNotFoundException', 'Cake\ORM\Error\RecordNotFoundException');
 class_alias('Cake\Network\Exception\BadRequestException', 'Cake\Error\BadRequestException');
 class_alias('Cake\Network\Exception\ForbiddenException', 'Cake\Error\ForbiddenException');

+ 1 - 1
src/ORM/Exception/RecordNotFoundException.php

@@ -12,7 +12,7 @@
  * @since         3.0.0
  * @license       http://www.opensource.org/licenses/mit-license.php MIT License
  */
-namespace Cake\ORM\Exception;
+namespace Cake\Datasource\Exception;
 
 use RuntimeException;
 

+ 18 - 0
src/Datasource/QueryTrait.php

@@ -15,6 +15,7 @@
 namespace Cake\Datasource;
 
 use Cake\Collection\Iterator\MapReduce;
+use Cake\Datasource\Exception\RecordNotFoundException;
 use Cake\Datasource\QueryCacher;
 use Cake\Datasource\RepositoryInterface;
 
@@ -329,6 +330,23 @@ trait QueryTrait {
 	}
 
 /**
+ * Get the first result from the executing query or raise an exception.
+ *
+ * @throws \Cake\Datasource\Exception\RecordNotFoundException When there is no first record.
+ * @return mixed The first result from the ResultSet.
+ */
+	public function firstOrFail() {
+		$entity = $this->first();
+		if ($entity) {
+			return $entity;
+		}
+		throw new RecordNotFoundException(sprintf(
+			'Record not found in table "%s"',
+			$this->repository()->table()
+		));
+	}
+
+/**
  * Returns an array with the custom options that were applied to this query
  * and that were not already processed by another method in this class.
  *

+ 1 - 14
src/ORM/Table.php

@@ -30,7 +30,6 @@ use Cake\ORM\Association\HasMany;
 use Cake\ORM\Association\HasOne;
 use Cake\ORM\BehaviorRegistry;
 use Cake\ORM\Exception\MissingEntityException;
-use Cake\ORM\Exception\RecordNotFoundException;
 use Cake\ORM\Marshaller;
 use Cake\Utility\Inflector;
 use Cake\Validation\Validator;
@@ -906,8 +905,6 @@ class Table implements RepositoryInterface, EventListenerInterface {
 /**
  * {@inheritDoc}
  *
- * @throws \Cake\ORM\Exception\RecordNotFoundException if no record can be found given
- * a primary key value.
  * @throws \InvalidArgumentException When $primaryKey has an incorrect number of elements.
  */
 	public function get($primaryKey, $options = []) {
@@ -941,17 +938,7 @@ class Table implements RepositoryInterface, EventListenerInterface {
 			}
 			$query->cache($cacheKey, $cacheConfig);
 		}
-
-		$entity = $query->first();
-
-		if ($entity) {
-			return $entity;
-		}
-		throw new RecordNotFoundException(sprintf(
-			'Record "%s" not found in table "%s"',
-			implode(',', (array)$primaryKey),
-			$this->table()
-		));
+		return $query->firstOrFail();
 	}
 
 /**

+ 5 - 5
tests/TestCase/ORM/TableTest.php

@@ -3389,7 +3389,7 @@ class TableTest extends TestCase {
 
 		$query = $this->getMock(
 			'\Cake\ORM\Query',
-			['addDefaultTypes', 'first', 'where', 'cache'],
+			['addDefaultTypes', 'firstOrFail', 'where', 'cache'],
 			[$this->connection, $table]
 		);
 
@@ -3404,7 +3404,7 @@ class TableTest extends TestCase {
 			->with([$table->alias() . '.bar' => 10])
 			->will($this->returnSelf());
 		$query->expects($this->never())->method('cache');
-		$query->expects($this->once())->method('first')
+		$query->expects($this->once())->method('firstOrFail')
 			->will($this->returnValue($entity));
 		$result = $table->get(10, $options);
 		$this->assertSame($entity, $result);
@@ -3449,7 +3449,7 @@ class TableTest extends TestCase {
 
 		$query = $this->getMock(
 			'\Cake\ORM\Query',
-			['addDefaultTypes', 'first', 'where', 'cache'],
+			['addDefaultTypes', 'firstOrFail', 'where', 'cache'],
 			[$this->connection, $table]
 		);
 
@@ -3466,7 +3466,7 @@ class TableTest extends TestCase {
 		$query->expects($this->once())->method('cache')
 			->with($cacheKey, $cacheConfig)
 			->will($this->returnSelf());
-		$query->expects($this->once())->method('first')
+		$query->expects($this->once())->method('firstOrFail')
 			->will($this->returnValue($entity));
 		$result = $table->get(10, $options);
 		$this->assertSame($entity, $result);
@@ -3476,7 +3476,7 @@ class TableTest extends TestCase {
  * Tests that get() will throw an exception if the record was not found
  *
  * @expectedException \Cake\ORM\Exception\RecordNotFoundException
- * @expectedExceptionMessage Record "10" not found in table "articles"
+ * @expectedExceptionMessage Record not found in table "articles"
  * @return void
  */
 	public function testGetNotFoundException() {