Yii2:模块内的可配置模型
Yii2: Configurable models inside module
以可配置的方式将 models/activerecords 包含在 Yii2 模块中的最佳做法是什么?
这些只是我们在使用包含在模块中的 activerecord 时面临的一些问题:
向模块提供的 models/activerecords 添加事件和行为。我想使用 Yii2 configuration format 将事件和行为附加到模块中包含的模型。这怎么能做到?
定义与存在于模块外部的 models/activerecords 的关系。将模块中包含的活动记录链接到用户活动记录时,我们可以依赖 Ỳii::$app->user->identityClass
,但对于其他自定义关系,我们可能需要扩展活动记录。有没有更好的方法?从模块扩展 activerecord 类 在某种程度上违背了模块化的目的。
在 module/activerecord 中配置各种其他变量。假设我们要调整最大字符串长度验证值。在模块控制器中,我们总是可以使用 $this->module->params
来读取任何自定义值,但我们不能从模型或 ActiveRecord 中执行此操作。我们应该怎么做呢?
我想你最终可能会使用 dependency injection:
写一个扩展“\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 年 7 月,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 中使用这些值(例如,在进行验证时)。
以可配置的方式将 models/activerecords 包含在 Yii2 模块中的最佳做法是什么?
这些只是我们在使用包含在模块中的 activerecord 时面临的一些问题:
向模块提供的 models/activerecords 添加事件和行为。我想使用 Yii2 configuration format 将事件和行为附加到模块中包含的模型。这怎么能做到?
定义与存在于模块外部的 models/activerecords 的关系。将模块中包含的活动记录链接到用户活动记录时,我们可以依赖
Ỳii::$app->user->identityClass
,但对于其他自定义关系,我们可能需要扩展活动记录。有没有更好的方法?从模块扩展 activerecord 类 在某种程度上违背了模块化的目的。在 module/activerecord 中配置各种其他变量。假设我们要调整最大字符串长度验证值。在模块控制器中,我们总是可以使用
$this->module->params
来读取任何自定义值,但我们不能从模型或 ActiveRecord 中执行此操作。我们应该怎么做呢?
我想你最终可能会使用 dependency injection:
写一个扩展“\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 年 7 月,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 中使用这些值(例如,在进行验证时)。