Yii2. Добавление динамического атрибута и правила к модели

Я пишу виджет, и я хочу, чтобы пользователь не добавлял код в свою модель (я знаю, что было бы проще, но использовать его, чтобы узнать что-то новое).

Знаете ли вы, можно ли добавить в модель атрибут (который отсутствует в вашей базе данных, так что он будет виртуальным) и добавить правило для этого атрибута ?. У вас нет доступа к изменению этого кода модели.

Я знаю, что правила – это массив. В прошлом я объединил правила из родительского класса с помощью array_merge. Можно ли это сделать извне? У Yii2 есть метод для этого?

Идея состоит в том, чтобы расширить модель, предоставленную пользователем, с помощью «модели» внутри моего виджета, и там используется:

public function init() { /*Since it is extended this not even would be necessary, I could declare the attribute as usual*/ $attribute = "categories"; $this->{$attribute} = null; //To create attribute on the fly parent::init(); } public function rules() { $rules = [...]; //Then here merge parent rules with mine. return array_merge(parent::rules, $rules); } 

Но если я его продюсирую, когда я использую эту модель в ActiveForm в примере для флажка, она будет использовать мой «CustomModel», поэтому я хочу этого избежать. Любые другие идеи? Как это сделать без расширения их модели?

Добавить динамические атрибуты в существующую модель

Если вы хотите добавить динамические атрибуты во время выполнения к существующей модели. Затем вам нужен какой-то пользовательский код, вам нужны: Model-Class и расширенный класс, который будет выполнять динамическую часть и иметь массив для хранения динамической информации. Эти массивы будут объединены в нужную функцию с возвращаемыми массивами Model-Class.

Вот своего рода макет, он не полностью работает. Но, может быть, вы поняли, что вам нужно сделать:

 class MyDynamicModel extends MyNoneDynamicModel { private $dynamicFields = []; private $dynamicRules = []; public function setDynamicFields($aryDynamics) { $this->dynamicFields = $aryDynamics; } public function setDynamicRules($aryDynamics) { $this->dynamicRules = $aryDynamics; } public function __get($name) { if (isset($this->dynamicFields[$name])) { return $this->dynamicFields[$name]; } return parent::__get($name); } public function __set($name, $value) { if (isset($this->dynamicFields[$name])) { return $this->dynamicFields[$name] = $value; } return parent::__set($name, $value); } public function rules() { return array_merge(parent::rules, $this->dynamicRules); } } 

Полные динамические атрибуты

Когда все атрибуты являются динамическими, и вам не нужна база данных. Затем используйте новую динамическую модель Yii2. В документе также говорится:

DynamicModel – это модельный класс, в основном используемый для поддержки проверки ad hoc.

Вот полный пример с интеграцией форм из Yii2-Wiki, поэтому я не приводил здесь пример.

Виртуальные атрибуты

Если вы хотите добавить атрибут к модели, которой нет в базе данных. Затем просто объявите общедоступную переменную в модели:

 public $myVirtualAttribute; 

Затем вы можете просто использовать его в правилах, как и другие атрибуты (database-).

Чтобы выполнить Massive Assignment , не забудьте добавить безопасное правило к правилам модели:

 public function rules() { return [ ..., [['myVirtualAttribute'], 'safe'], ... ]; } 

Причина этого очень хорошо объясняется здесь: Yii2 не-DB (или виртуальный) атрибут не заполняется во время массового присвоения?