Commit 796284cb by Carsten Brandt

reworked fix for #1993

parent 81d23332
......@@ -103,7 +103,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface
}
unset($row);
}
$models = $this->createModels($result['hits']['hits'], false);
$models = $this->createModels($result['hits']['hits']);
if ($this->asArray && !$this->indexBy) {
foreach($models as $key => $model) {
if ($pk === '_id') {
......@@ -149,7 +149,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface
} else {
/** @var ActiveRecord $class */
$class = $this->modelClass;
$model = $class::create($result, false);
$model = $class::create($result);
}
if (!empty($this->with)) {
$models = [$model];
......@@ -169,7 +169,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface
{
$result = $this->createCommand($db)->search($options);
if (!empty($result['hits']['hits'])) {
$models = $this->createModels($result['hits']['hits'], false);
$models = $this->createModels($result['hits']['hits']);
if ($this->asArray) {
/** @var ActiveRecord $modelClass */
$modelClass = $this->modelClass;
......
......@@ -91,7 +91,9 @@ class ActiveRecord extends BaseActiveRecord
$command = static::getDb()->createCommand();
$result = $command->get(static::index(), static::type(), $primaryKey, $options);
if ($result['exists']) {
return static::create($result);
$model = static::create($result);
$model->afterFind();
return $model;
}
return null;
}
......@@ -118,7 +120,9 @@ class ActiveRecord extends BaseActiveRecord
$models = [];
foreach($result['docs'] as $doc) {
if ($doc['exists']) {
$models[] = static::create($doc);
$model = static::create($doc);
$model->afterFind();
$models[] = $model;
}
}
return $models;
......@@ -261,22 +265,17 @@ class ActiveRecord extends BaseActiveRecord
* This method is called by [[ActiveQuery]] to populate the query results
* into Active Records. It is not meant to be used to create new records.
* @param array $row attribute values (name => value)
* @param bool $callAfterFind whether this is a create after find and afterFind() should be called directly after create.
* This may be set to false to call afterFind later.
* @return ActiveRecord the newly created active record.
*/
public static function create($row, $callAfterFind = true)
public static function create($row)
{
$record = parent::create($row['_source'], false);
$record = parent::create($row['_source']);
$pk = static::primaryKey()[0];
if ($pk === '_id') {
$record->$pk = $row['_id'];
}
$record->_score = isset($row['_score']) ? $row['_score'] : null;
$record->_version = isset($row['_version']) ? $row['_version'] : null; // TODO version should always be available...
if ($callAfterFind) {
$record->afterFind();
}
return $record;
}
......
......@@ -4,7 +4,7 @@ Yii Framework 2 elasticsearch extension Change Log
2.0.0 beta under development
----------------------------
- Bug #1993: afterFind event in AR is now called after relations have been populated (cebe)
- Bug #1993: afterFind event in AR is now called after relations have been populated (cebe, creocoder)
- Enh #1382: Added a debug toolbar panel for elasticsearch (cebe)
- Enh #1765: Added support for primary key path mapping, pk can now be part of the attributes when mapping is defined (cebe)
- Chg #1765: Changed handling of ActiveRecord primary keys, removed getId(), use getPrimaryKey() instead (cebe)
......
......@@ -49,9 +49,10 @@ class ActiveQuery extends Query implements ActiveQueryInterface
$cursor = $this->buildCursor($db);
$rows = $this->fetchRows($cursor);
if (!empty($rows)) {
$models = $this->createModels($rows);
if (!empty($this->with)) {
$models = $this->createModels($rows, false);
$this->findWith($this->with, $models);
}
if (!$this->asArray) {
foreach($models as $model) {
$model->afterFind();
......@@ -59,9 +60,6 @@ class ActiveQuery extends Query implements ActiveQueryInterface
}
return $models;
} else {
return $this->createModels($rows);
}
} else {
return [];
}
}
......@@ -83,7 +81,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface
} else {
/** @var ActiveRecord $class */
$class = $this->modelClass;
$model = $class::create($row, false);
$model = $class::create($row);
}
if (!empty($this->with)) {
$models = [$model];
......
......@@ -49,9 +49,10 @@ class ActiveQuery extends Query implements ActiveQueryInterface
$cursor = $this->buildCursor($db);
$rows = $this->fetchRows($cursor);
if (!empty($rows)) {
$models = $this->createModels($rows);
if (!empty($this->with)) {
$models = $this->createModels($rows, false);
$this->findWith($this->with, $models);
}
if (!$this->asArray) {
foreach($models as $model) {
$model->afterFind();
......@@ -59,9 +60,6 @@ class ActiveQuery extends Query implements ActiveQueryInterface
}
return $models;
} else {
return $this->createModels($rows);
}
} else {
return [];
}
}
......@@ -83,7 +81,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface
} else {
/** @var ActiveRecord $class */
$class = $this->modelClass;
$model = $class::create($row, false);
$model = $class::create($row);
}
if (!empty($this->with)) {
$models = [$model];
......
......@@ -72,9 +72,10 @@ class ActiveQuery extends \yii\base\Component implements ActiveQueryInterface
$rows[] = $row;
}
if (!empty($rows)) {
$models = $this->createModels($rows);
if (!empty($this->with)) {
$models = $this->createModels($rows, false);
$this->findWith($this->with, $models);
}
if (!$this->asArray) {
foreach($models as $model) {
$model->afterFind();
......@@ -82,9 +83,6 @@ class ActiveQuery extends \yii\base\Component implements ActiveQueryInterface
}
return $models;
} else {
return $this->createModels($rows);
}
} else {
return [];
}
}
......@@ -114,7 +112,7 @@ class ActiveQuery extends \yii\base\Component implements ActiveQueryInterface
} else {
/** @var ActiveRecord $class */
$class = $this->modelClass;
$model = $class::create($row, false);
$model = $class::create($row);
}
if (!empty($this->with)) {
$models = [$model];
......
......@@ -4,7 +4,7 @@ Yii Framework 2 redis extension Change Log
2.0.0 beta under development
----------------------------
- Bug #1993: afterFind event in AR is now called after relations have been populated (cebe)
- Bug #1993: afterFind event in AR is now called after relations have been populated (cebe, creocoder)
- Enh #1773: keyPrefix property of Session and Cache is not restricted to alnum characters anymore (cebe)
2.0.0 alpha, December 1, 2013
......
......@@ -105,7 +105,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface
$command = $this->createCommand($db);
$rows = $command->queryAll();
if (!empty($rows)) {
$models = $this->createModels($rows, false);
$models = $this->createModels($rows);
if (!empty($this->with)) {
$this->findWith($this->with, $models);
}
......@@ -139,7 +139,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface
} else {
/** @var $class ActiveRecord */
$class = $this->modelClass;
$model = $class::create($row, false);
$model = $class::create($row);
}
if (!empty($this->with)) {
$models = [$model];
......
......@@ -623,11 +623,9 @@ abstract class ActiveRecord extends BaseActiveRecord
* This method is called by [[ActiveQuery]] to populate the query results
* into Active Records. It is not meant to be used to create new records.
* @param array $row attribute values (name => value)
* @param bool $callAfterFind whether this is a create after find and afterFind() should be called directly after create.
* This may be set to false to call afterFind later.
* @return ActiveRecord the newly created active record.
*/
public static function create($row, $callAfterFind = true)
public static function create($row)
{
$record = static::instantiate($row);
$columns = static::getIndexSchema()->columns;
......@@ -643,9 +641,6 @@ abstract class ActiveRecord extends BaseActiveRecord
}
}
$record->setOldAttributes($record->getAttributes());
if ($callAfterFind) {
$record->afterFind();
}
return $record;
}
......
......@@ -4,7 +4,7 @@ Yii Framework 2 sphinx extension Change Log
2.0.0 beta under development
----------------------------
- Bug #1993: afterFind event in AR is now called after relations have been populated (cebe)
- Bug #1993: afterFind event in AR is now called after relations have been populated (cebe, creocoder)
- Enh #1398: Refactor ActiveRecord to use BaseActiveRecord class of the framework (klimov-paul)
2.0.0 alpha, December 1, 2013
......
......@@ -29,7 +29,7 @@ Yii Framework 2 Change Log
- Bug #1937: Fixed wrong behavior or advanced app's `init --env` when called without parameter actually specified (samdark)
- Bug #1959: `Html::activeCheckbox` wasn't respecting custom values for checked/unchecked state (klevron, samdark)
- Bug #1965: `Controller::findLayoutFile()` returns incorrect file path when layout name starts with a slash (qiangxue)
- Bug #1993: afterFind event in AR is now called after relations have been populated (cebe)
- Bug #1993: afterFind event in AR is now called after relations have been populated (cebe, creocoder)
- Bug: Fixed `Call to a member function registerAssetFiles() on a non-object` in case of wrong `sourcePath` for an asset bundle (samdark)
- Bug: Fixed incorrect event name for `yii\jui\Spinner` (samdark)
- Bug: Json::encode() did not handle objects that implement JsonSerializable interface correctly (cebe)
......
......@@ -67,7 +67,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface
$command = $this->createCommand($db);
$rows = $command->queryAll();
if (!empty($rows)) {
$models = $this->createModels($rows, false);
$models = $this->createModels($rows);
if (!empty($this->join) && $this->indexBy === null) {
$models = $this->removeDuplicatedModels($models);
}
......@@ -144,7 +144,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface
} else {
/** @var ActiveRecord $class */
$class = $this->modelClass;
$model = $class::create($row, false);
$model = $class::create($row);
}
if (!empty($this->with)) {
$models = [$model];
......
......@@ -135,7 +135,7 @@ trait ActiveQueryTrait
* @param bool $callAfterFind
* @return array|ActiveRecord[]
*/
private function createModels($rows, $callAfterFind = true)
private function createModels($rows)
{
$models = [];
if ($this->asArray) {
......@@ -155,11 +155,11 @@ trait ActiveQueryTrait
$class = $this->modelClass;
if ($this->indexBy === null) {
foreach ($rows as $row) {
$models[] = $class::create($row, $callAfterFind);
$models[] = $class::create($row);
}
} else {
foreach ($rows as $row) {
$model = $class::create($row, $callAfterFind);
$model = $class::create($row);
if (is_string($this->indexBy)) {
$key = $model->{$this->indexBy};
} else {
......
......@@ -983,15 +983,21 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
}
/**
* Creates an active record object using a row of data.
* This method is called by [[ActiveQuery]] to populate the query results
* into Active Records. It is not meant to be used to create new records.
* Creates an active record object using a row of data from the database/storage.
*
* This method is *not* meant to be used to create new records.
*
* It is an internal method meant to be called to create active record objects after
* fetching data from the database. It is mainly used by [[ActiveQuery]] to populate
* the query results into Active Records.
*
* When calling this method manually you should call [[afterFind()]] on the created
* record to trigger the [[EVENT_AFTER_FIND|afterFind Event]].
*
* @param array $row attribute values (name => value)
* @param bool $callAfterFind whether this is a create after find and afterFind() should be called directly after create.
* This may be set to false to call afterFind later.
* @return ActiveRecord the newly created active record.
* @return static the newly created active record.
*/
public static function create($row, $callAfterFind = true)
public static function create($row)
{
$record = static::instantiate($row);
$columns = array_flip($record->attributes());
......@@ -1003,9 +1009,6 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
}
}
$record->_oldAttributes = $record->_attributes;
if ($callAfterFind) {
$record->afterFind();
}
return $record;
}
......@@ -1017,7 +1020,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
* For example, by creating a record based on the value of a column,
* you may implement the so-called single-table inheritance mapping.
* @param array $row row data to be populated into the record.
* @return ActiveRecord the newly created active record
* @return static the newly created active record
*/
public static function instantiate($row)
{
......
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