Yii2: конфигурируемые модели внутри модуля

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

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

  1. Добавление событий и поведения к моделям / активным записям, предоставляемым модулем. Я хочу прикрепить события и поведения к моделям, включенным в модуль, используя формат конфигурации Yii2. Как это может быть сделано?

  2. Определение отношений с моделями / активными записями, существующими вне модуля. При связывании активной записи, содержащейся в модуле, с активной записью пользователя, мы можем положиться Ỳii::$app->user->identityClass, но для других пользовательских отношений нам может понадобиться расширить activerecord. Есть ли лучший подход? Расширение классов activerecord из модулей несколько отрицательно сказывается на модульности.

  3. Настройка различных других переменных в модуле / 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!

Увидеть:

Единственный способ обойти это - настроить ваши модули через Yii::$app->params а затем использовать эти значения внутри модуля AR (например, при выполнении проверки).

Другие вопросы по тегам