Yii2: Configurable models inside module

女生的网名这么多〃 提交于 2019-12-01 13:10:50

问题


What is the best practice of including models/activerecords within a Yii2 module in a way that they are configurable?

These are just some of the problems we face when we want to use an activerecord included inside a module:

  1. Adding events & behaviors to models/activerecords provided by a module. I want to attach events and behaviors to the models included in a module using Yii2's configuration format. How can this be done?

  2. Defining relations with models/activerecords that exist outside of the module. When linking an activerecord contained inside a module to the User activerecord we can rely on Ỳii::$app->user->identityClass, but for other custom relations we might need to extend the activerecord. Is there any better approach? Extending activerecord classes from modules somewhat defeats the purpose of modularity.

  3. Configuring various other variables within the module/activerecord. Let's say we want to adjust the max string length validation value. In a module Controller, we can always use $this->module->params to read any custom value, but we cannot do this from a Model or an ActiveRecord. What are we supposed to do instead?


回答1:


I think you might end up using dependency injection:

Write an extension "\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");
    }
}

add to your config:

'bootstrap' => [
    'common\extensions\MyBootstrap',
],

'components' => [ 
    //  ... 
]

and in your code you have to use Yii::$container->get():

$test = Yii::$container->get('common\modules\test\models\Test1');
var_dump($test);

which will create Test2 model instead of Test1. If you want this to happen for your ActiveRecord, override this:

public static function instantiate($row) {
    return \Yii::$container->get(static::class);
}



回答2:


EDIT: The underlying issue has now been resolved. We can use DI to inject relations into ActiveRecords.

As of July 2017, Yii2 does not allow ActiveRecord dependency injection!

See:

  • 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

The only way around this is to configure your modules through your Yii::$app->params and then use those values inside module ARs (eg. when doing validation).



来源:https://stackoverflow.com/questions/38582341/yii2-configurable-models-inside-module

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!