Yii2: как установить значения атрибутов по умолчанию в ActiveRecord?

это может показаться тривиальным вопросом, но все очевидные решения, которые я думаю, имеют свои недостатки.

мы хотим иметь возможность устанавливать любое значение атрибута ActiveRecord по умолчанию только для новых записей таким образом, чтобы оно было читаемым до и во время проверки и не мешало производным классам, используемым для поиска.

значения по умолчанию должны быть установлены и готовы, как только мы создаем экземпляр класса, так что (new MyModel)->attr возвращает по умолчанию attr значение.

вот некоторые из возможностей и проблем, которые они имеют:

  • A) на MyModel переопределить init() метод и присвоить значение по умолчанию, когда isNewRecord верно так:

    public function init() {
        if ($this->isNewRecord) {
            $this->attr = 'defaultValue';
        }
        parent::init();
    }
    

5 ответов


Я знаю, что на него ответили, но я добавлю свой подход. У меня есть модели Application и ApplicationSearch. В модели приложения я добавляю init с проверкой текущего экземпляра. Если его ApplicationSearch я пропускаю инициализации.

    public function init()
    { 
        if(!$this instanceof ApplicationSearch)  
        {
            $this->id = hash('sha256',  123);
        }

        parent::init();
    }

также, как @ mae прокомментировал ниже, вы можете проверить наличие метода поиска в текущем экземпляре, предполагая, что вы не добавили какой-либо метод с поиском имени в базовую модель без поиска, поэтому код становится:

    public function init()
    { 
        // no search method is available in Gii generated Non search class
        if(!method_exists($this,'search'))  
        {
            $this->id = hash('sha256',  123);
        }

        parent::init();
    }

есть два способа сделать это.

$model => new Model();

теперь $model имеет все атрибуты по умолчанию из таблицы базы данных.

или в ваших правилах вы можете использовать:

[['field_name'], 'default', 'value'=> $defaultValue],

теперь $model всегда создается со значениями по умолчанию, которые вы указали.

вы можете увидеть полный список основных валидаторов здесь http://www.yiiframework.com/doc-2.0/guide-tutorial-core-validators.html


Я прочитал Ваш вопрос несколько раз, и я думаю, что есть некоторые противоречия.
Вы хотите, чтобы значения по умолчанию считывались до и во время проверки, а затем попробуйте init() или beforeSave(). Поэтому, предполагая, что вы просто хотите установить значения по умолчанию в модели, чтобы они могли присутствовать в течение части жизненного цикла как можно дольше и не мешать производным классам, просто установите их после инициализации объекта.

вы можете подготовить отдельный метод где все значения по умолчанию устанавливаются и вызываются явно.

$model = new Model;
$model->setDefaultValues();

или вы можете создать статический метод для создания модели со всеми значениями по умолчанию и возвращает его экземпляр.

$model = Model::createNew();

или вы можете передать конструктору значения по умолчанию.

$model = new Model([
    'attribute1' => 'value1',
    'attribute2' => 'value2',
]);

это не сильно отличается от установки атрибутов напрямую.

$model = new Model;
$model->attribute1 = 'value1';
$model->attribute2 = 'value2';

все зависит от того, насколько прозрачной вы хотите, чтобы ваша модель была для вашего контроллера.

этот путь атрибуты устанавливаются для всего жизненного цикла, кроме прямой инициализации, и это не мешает производной модели поиска.


просто переопределить __construct() метод в вашей модели такой:

class MyModel extends \yii\db\ActiveRecord {

    function __construct(array $config = [])
       {
           parent::__construct($config);
           $this->attr = 'defaultValue';
       }
    ...
}

вы можете подготовить отдельный метод, где все по умолчанию и вызвать его явно.

$model = new Model;
if($model->isNewRecord())
    $model->setDefaultValues();