Commit 338b6aa7 by Qiang Xue

Refactored ActiveRecord::find() so that find(null) will also return an…

Refactored ActiveRecord::find() so that find(null) will also return an ActiveRecord instance instead of ActiveQuery.
parent 2c31305f
...@@ -68,13 +68,17 @@ class ActiveRecord extends BaseActiveRecord ...@@ -68,13 +68,17 @@ class ActiveRecord extends BaseActiveRecord
public static function find($q = null) public static function find($q = null)
{ {
$query = static::createQuery(); $query = static::createQuery();
$args = func_get_args();
if (empty($args)) {
return $query;
}
$q = reset($args);
if (is_array($q)) { if (is_array($q)) {
return $query->andWhere($q)->one(); return $query->andWhere($q)->one();
} elseif ($q !== null) { } else {
return static::get($q); return static::get($q);
} }
return $query;
} }
/** /**
......
...@@ -142,18 +142,15 @@ class <?= $controllerClass ?> extends <?= StringHelper::basename($generator->bas ...@@ -142,18 +142,15 @@ class <?= $controllerClass ?> extends <?= StringHelper::basename($generator->bas
<?php <?php
if (count($pks) === 1) { if (count($pks) === 1) {
$condition = '$id'; $condition = '$id';
// find() would return Query when $id === null
$nullCheck = '$id !== null && ';
} else { } else {
$condition = []; $condition = [];
foreach ($pks as $pk) { foreach ($pks as $pk) {
$condition[] = "'$pk' => \$$pk"; $condition[] = "'$pk' => \$$pk";
} }
$condition = '[' . implode(', ', $condition) . ']'; $condition = '[' . implode(', ', $condition) . ']';
$nullCheck = '';
} }
?> ?>
if (<?= $nullCheck ?>($model = <?= $modelClass ?>::find(<?= $condition ?>)) !== null) { if (($model = <?= $modelClass ?>::find(<?= $condition ?>)) !== null) {
return $model; return $model;
} else { } else {
throw new NotFoundHttpException('The requested page does not exist.'); throw new NotFoundHttpException('The requested page does not exist.');
......
...@@ -96,25 +96,51 @@ interface ActiveRecordInterface ...@@ -96,25 +96,51 @@ interface ActiveRecordInterface
/** /**
* Creates an [[ActiveQueryInterface|ActiveQuery]] instance for query purpose. * Creates an [[ActiveQueryInterface|ActiveQuery]] instance for query purpose.
* *
* This method is usually ment to be used like this: * The returned [[ActiveQueryInterface|ActiveQuery]] instance can be further customized by calling
* methods defined in [[ActiveQueryInterface]] before `one()` or `all()` is called to return
* populated ActiveRecord instances. For example,
* *
* ```php * ```php
* Customer::find(1); // find one customer by primary key * // find the customer whose ID is 1
* Customer::find()->all(); // find all customers * $customer = Customer::find()->where(['id' => 1])->one();
*
* // find all active customers and order them by their age:
* $customers = Customer::find()
* ->where(['status' => 1])
* ->orderBy('age')
* ->all();
* ``` * ```
* *
* @param mixed $q the query parameter. This can be one of the followings: * This method can also take a parameter which can be:
* *
* - a scalar value (integer or string): query by a single primary key value and return the * - a scalar value (integer or string): query by a single primary key value and return the
* corresponding record. * corresponding record (or null if not found).
* - an array of name-value pairs: query by a set of attribute values and return a single record matching all of them. * - an array of name-value pairs: query by a set of attribute values and return a single record
* - null (not specified): return a new [[ActiveQuery]] object for further query purpose. * matching all of them (or null if not found).
* *
* @return ActiveQueryInterface|static|null When `$q` is null, a new [[ActiveQuery]] instance * Note that in this case, the method will automatically call the `one()` method and return an
* is returned; when `$q` is a scalar or an array, an ActiveRecord object matching it will be * [[ActiveRecordInterface|ActiveRecord]] instance. For example,
* returned (null will be returned if there is no matching). *
* ```php
* // find a single customer whose primary key value is 10
* $customer = Customer::find(10);
*
* // the above code is equivalent to:
* $customer = Customer::find()->where(['id' => 10])->one();
*
* // find a single customer whose age is 30 and whose status is 1
* $customer = Customer::find(['age' => 30, 'status' => 1]);
*
* // the above code is equivalent to:
* $customer = Customer::find()->where(['age' => 30, 'status' => 1])->one();
* ```
*
* @return ActiveQueryInterface|static|null When this method receives no parameter, a new [[ActiveQuery]] instance
* will be returned; Otherwise, the parameter will be treated as a primary key value or a set of column
* values, and an ActiveRecord object matching it will be returned (null will be returned if there is no matching).
* @see createQuery()
*/ */
public static function find($q = null); public static function find();
/** /**
* Creates an [[ActiveQueryInterface|ActiveQuery]] instance. * Creates an [[ActiveQueryInterface|ActiveQuery]] instance.
......
...@@ -92,54 +92,20 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface ...@@ -92,54 +92,20 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
private $_related = []; private $_related = [];
/** /**
* Creates an [[ActiveQuery]] instance for query purpose. * @inheritdoc
*
* The returned [[ActiveQuery]] instance can be further customized by calling
* methods defined in [[ActiveQuery]] before `one()`, `all()` or `value()` is
* called to return the populated active records:
*
* ~~~
* // find all customers
* $customers = Customer::find()->all();
*
* // find all active customers and order them by their age:
* $customers = Customer::find()
* ->where(['status' => 1])
* ->orderBy('age')
* ->all();
*
* // find a single customer whose primary key value is 10
* $customer = Customer::find(10);
*
* // the above is equivalent to:
* $customer = Customer::find()->where(['id' => 10])->one();
*
* // find a single customer whose age is 30 and whose status is 1
* $customer = Customer::find(['age' => 30, 'status' => 1]);
*
* // the above is equivalent to:
* $customer = Customer::find()->where(['age' => 30, 'status' => 1])->one();
* ~~~
*
* @param mixed $q the query parameter. This can be one of the followings:
*
* - a scalar value (integer or string): query by a single primary key value and return the
* corresponding record.
* - an array of name-value pairs: query by a set of column values and return a single record matching all of them.
* - null: return a new [[ActiveQuery]] object for further query purpose.
*
* @return ActiveQuery|static|null When `$q` is null, a new [[ActiveQuery]] instance
* is returned; when `$q` is a scalar or an array, an ActiveRecord object matching it will be
* returned (null will be returned if there is no matching).
* @throws InvalidConfigException if the AR class does not have a primary key
* @see createQuery()
*/ */
public static function find($q = null) public static function find()
{ {
$query = static::createQuery(); $query = static::createQuery();
$args = func_get_args();
if (empty($args)) {
return $query;
}
$q = reset($args);
if (is_array($q)) { if (is_array($q)) {
return $query->andWhere($q)->one(); return $query->andWhere($q)->one();
} elseif ($q !== null) { } else {
// query by primary key // query by primary key
$primaryKey = static::primaryKey(); $primaryKey = static::primaryKey();
if (isset($primaryKey[0])) { if (isset($primaryKey[0])) {
...@@ -148,8 +114,6 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface ...@@ -148,8 +114,6 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
throw new InvalidConfigException(get_called_class() . ' must have a primary key.'); throw new InvalidConfigException(get_called_class() . ' must have a primary key.');
} }
} }
return $query;
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment