diff --git a/docs/guide/active-record.md b/docs/guide/active-record.md index b4dfada..0b112c1 100644 --- a/docs/guide/active-record.md +++ b/docs/guide/active-record.md @@ -198,6 +198,15 @@ Customer::updateAllCounters(['age' => 1]); > Info: The `save()` method will either perform an `INSERT` or `UPDATE` SQL statement, depending on whether the ActiveRecord being saved is new or not by checking `ActiveRecord::isNewRecord`. +In order to load default values from database schema you may call `loadDefaultValues()` method: + +```php +$customer = new Customer(); +$customer->loadDefaultValues(); +$cusomer->name = 'Alexander'; +$customer->save(); +``` + Data Input and Validation ------------------------- diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 5c13470..52c0bf1 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -146,6 +146,7 @@ Yii Framework 2 Change Log - Enh #2661: Added boolean column type support for SQLite (qiangxue) - Enh #2670: Changed `console\Controller::globalOptions()` to `options($actionId)` to (make it possible to) differentiate options per action (hqx) - Enh #2714: Added support for formatting time intervals relative to the current time with `yii\base\Formatter` (drenty) +- Enh #2726: Added `yii\db\ActiveRecord::loadDefaultValues()` that fills default values from DB schema (samdark) - Enh #2729: Added `FilterValidator::skipOnArray` so that filters like `trim` will not fail for array inputs (qiangxue) - Enh #2735: Added support for `DateTimeInterface` in `Formatter` (ivokund) - Enh #2756: Added support for injecting custom `isEmpty` check for all validators (qiangxue) diff --git a/framework/db/ActiveRecord.php b/framework/db/ActiveRecord.php index ad895e6..c549c14 100644 --- a/framework/db/ActiveRecord.php +++ b/framework/db/ActiveRecord.php @@ -94,6 +94,21 @@ class ActiveRecord extends BaseActiveRecord const OP_ALL = 0x07; /** + * Loads default values from database table schema + * + * @return static model instance + */ + public function loadDefaultValues() + { + foreach ($this->getTableSchema()->columns as $column) { + if ($column->defaultValue) { + $this->{$column->name} = $column->defaultValue; + } + } + return $this; + } + + /** * Returns the database connection used by this AR class. * By default, the "db" application component is used as the database connection. * You may override this method if you want to use a different database connection. diff --git a/tests/unit/data/ar/Type.php b/tests/unit/data/ar/Type.php new file mode 100644 index 0000000..9dce4f6 --- /dev/null +++ b/tests/unit/data/ar/Type.php @@ -0,0 +1,31 @@ +<?php + +namespace yiiunit\data\ar; + +/** + * Model representing tbl_type table + * + * @property int $int_col + * @property int $int_col2 DEFAULT 1 + * @property string $char_col + * @property string $char_col2 DEFAULT 'something' + * @property string $char_col3 + * @property float $float_col + * @property float $float_col2 DEFAULT '1.23' + * @property string $blob_col + * @property float $numeric_col DEFAULT '33.22' + * @property string $time DEFAULT '2002-01-01 00:00:00' + * @property boolean $bool_col + * @property boolean $bool_col2 DEFAULT 1 + */ +class Type extends ActiveRecord +{ + /** + * @inheritdoc + */ + public static function tableName() + { + return 'tbl_type'; + } +} + \ No newline at end of file diff --git a/tests/unit/framework/db/ActiveRecordTest.php b/tests/unit/framework/db/ActiveRecordTest.php index 1f53e46..4ff83ab 100644 --- a/tests/unit/framework/db/ActiveRecordTest.php +++ b/tests/unit/framework/db/ActiveRecordTest.php @@ -8,6 +8,7 @@ use yiiunit\data\ar\OrderItem; use yiiunit\data\ar\Order; use yiiunit\data\ar\Item; use yiiunit\data\ar\Profile; +use yiiunit\data\ar\Type; use yiiunit\framework\ar\ActiveRecordTestTrait; /** @@ -486,4 +487,16 @@ class ActiveRecordTest extends DatabaseTestCase $this->assertTrue($orders[1]['customer2']['orders2'][0]['id'] === $orders[0]['id']); $this->assertTrue($orders[1]['customer2']['orders2'][1]['id'] === $orders[1]['id']); } + + public function testDefaultValues() + { + $model = new Type(); + $model->loadDefaultValues(); + $this->assertEquals(1, $model->int_col2); + $this->assertEquals('something', $model->char_col2); + $this->assertEquals(1.23, $model->float_col2); + $this->assertEquals(33.22, $model->numeric_col); + $this->assertEquals('2002-01-01 00:00:00', $model->time); + $this->assertEquals(true, $model->bool_col2); + } }