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();