Yii2: конфигурируемые модели внутри модуля
Каков наилучший способ включения моделей / активных записей в модуль Yii2 таким образом, чтобы их можно было настраивать?
Это лишь некоторые из проблем, с которыми мы сталкиваемся, когда хотим использовать активную запись, включенную в модуль:
Добавление событий и поведения к моделям / активным записям, предоставляемым модулем. Я хочу прикрепить события и поведения к моделям, включенным в модуль, используя формат конфигурации Yii2. Как это может быть сделано?
Определение отношений с моделями / активными записями, существующими вне модуля. При связывании активной записи, содержащейся в модуле, с активной записью пользователя, мы можем положиться
Ỳii::$app->user->identityClass
, но для других пользовательских отношений нам может понадобиться расширить activerecord. Есть ли лучший подход? Расширение классов activerecord из модулей несколько отрицательно сказывается на модульности.Настройка различных других переменных в модуле / activerecord. Допустим, мы хотим настроить значение проверки максимальной длины строки. В модуле Controller мы всегда можем использовать
$this->module->params
читать любое пользовательское значение, но мы не можем сделать это из модели или ActiveRecord. Что мы должны делать вместо этого?
2 ответа
Я думаю, что вы могли бы использовать инъекцию зависимости:
Напишите расширение "\common\extensions\MyBootstrap":
namespace common\extensions;
use Yii;
use yii\base\BootstrapInterface;
use yii\base\Application;
class MyBootstrap implements BootstrapInterface {
/**
* @param Application $app Application
**/
public function bootstrap($app) {
Yii::$container->set("common\\modules\\test\\models\\Test1", "common\\modules\\test\\models\\Test2");
}
}
добавьте в свой конфиг:
'bootstrap' => [
'common\extensions\MyBootstrap',
],
'components' => [
// ...
]
и в вашем коде вы должны использовать Yii::$container->get()
:
$test = Yii::$container->get('common\modules\test\models\Test1');
var_dump($test);
который создаст Test2
модель вместо Test1
, Если вы хотите, чтобы это произошло с вашей ActiveRecord, переопределите это:
public static function instantiate($row) {
return \Yii::$container->get(static::class);
}
РЕДАКТИРОВАТЬ: Основная проблема теперь решена. Мы можем использовать DI для внедрения отношений в ActiveRecords.
По состоянию на июль 2017 года Yii2 не разрешает внедрение зависимостей ActiveRecord!
Увидеть:
- https://github.com/yiisoft/yii2/issues/8639
- https://github.com/yiisoft/yii2/issues/11575
- https://github.com/yiisoft/yii2/issues/5786
- https://github.com/yiisoft/yii2/pull/14078
- https://github.com/yiisoft/yii2/issues/13779
Единственный способ обойти это - настроить ваши модули через Yii::$app->params
а затем использовать эти значения внутри модуля AR (например, при выполнении проверки).