Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize ActiveRecord::loadDefaultValues() #18993

Merged
merged 12 commits into from
Nov 11, 2021
1 change: 1 addition & 0 deletions framework/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Yii Framework 2 Change Log
- Bug #18909: Fix bug with binding default action parameters for controllers (bizley)
- Bug #18955: Check `yiisoft/yii2-swiftmailer` before using as default mailer in `yii\base\Application` (WinterSilence)
- Bug #18988: Fix default value of `yii\console\controllers\MessageController::$translator` (WinterSilence)
- Bug #18993: Load defaults by `attributes()` in `yii\db\ActiveRecord::loadDefaultValues()` (WinterSilence)


2.0.43 August 09, 2021
Expand Down
10 changes: 7 additions & 3 deletions framework/db/ActiveRecord.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,13 @@ class ActiveRecord extends BaseActiveRecord
*/
public function loadDefaultValues($skipIfSet = true)
{
foreach (static::getTableSchema()->columns as $column) {
if ($column->defaultValue !== null && (!$skipIfSet || $this->{$column->name} === null)) {
$this->{$column->name} = $column->defaultValue;
$columns = static::getTableSchema()->columns;
foreach ($this->attributes() as $name) {
if (isset($columns[$name])) {
$defaultValue = $columns[$name]->defaultValue;
if ($defaultValue !== null && (!$skipIfSet || $this->getAttribute($name) === null)) {
$this->setAttribute($name, $defaultValue);
}
}
}

Expand Down
33 changes: 33 additions & 0 deletions tests/data/ar/CroppedType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/

namespace yiiunit\data\ar;

/**
* Model representing 2 columns from "type" table.
*
* @property int $int_col
* @property int $int_col2 DEFAULT 1
*/
class CroppedType extends ActiveRecord
{
/**
* @inheritDoc
*/
public static function tableName()
{
return '{{%type}}';
}

/**
* @inheritDoc
*/
public function attributes()
{
return ['int_col', 'int_col2'];
}
}
9 changes: 6 additions & 3 deletions tests/framework/db/ActiveRecordTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
use yiiunit\data\ar\Profile;
use yiiunit\data\ar\ProfileWithConstructor;
use yiiunit\data\ar\Type;
use yiiunit\data\ar\CroppedType;
use yiiunit\framework\ar\ActiveRecordTestTrait;
use yiiunit\framework\db\cubrid\ActiveRecordTest as CubridActiveRecordTest;
use yiiunit\TestCase;
Expand Down Expand Up @@ -1344,7 +1345,6 @@ public function testDefaultValues()
$this->assertEquals(1.23, $model->float_col2);
$this->assertEquals(33.22, $model->numeric_col);
$this->assertEquals(true, $model->bool_col2);

if ($this instanceof CubridActiveRecordTest) {
// cubrid has non-standard timestamp representation
$this->assertEquals('12:00:00 AM 01/01/2002', $model->time);
Expand All @@ -1354,15 +1354,18 @@ public function testDefaultValues()

$model = new Type();
$model->char_col2 = 'not something';

$model->loadDefaultValues();
$this->assertEquals('not something', $model->char_col2);

$model = new Type();
$model->char_col2 = 'not something';

$model->loadDefaultValues(false);
$this->assertEquals('something', $model->char_col2);

// Cropped model with 2 attributes/columns
$model = new CroppedType();
$model->loadDefaultValues();
$this->assertEquals(['int_col2' => 1], $model->toArray());
}

public function testUnlinkAllViaTable()
Expand Down