antonyz89 / yii2-many-to-many
为 Yii 2 框架提供的多对多 ActiveRecord 关系。由 Alexey Rogachev 创建,AntonyZ89 分支
0.3.6
2023-08-12 18:07 UTC
Requires
- yiisoft/yii2: ~2.0.15
Requires (Dev)
- phpunit/dbunit: ~4.0
- phpunit/phpunit: ~7.1
README
实现 Yii 2 框架的多对多关系。
由 arogachev 创建,AntonyZ89 分支
安装
通过 composer 安装此扩展是首选方法。
运行以下命令之一:
php composer.phar require --prefer-dist antonyz89/yii2-many-to-many
或者
"antonyz89/yii2-many-to-many": "0.3.*"
将以下内容添加到你的 composer.json
文件的 require 部分。
特性
- 使用现有的
hasMany
关系进行配置 - 多关系
- 没有额外的查询。例如,如果最初模型有 100 个相关记录,添加一个后,将正好插入一行。如果没有更改,则不会执行查询。
- 自动填充可编辑属性
- 验证器用于检查接收到的列表是否有效
创建可编辑属性
简单地将公共属性添加到你的 ActiveRecord
模型中,如下所示
/** @var int[] */ public $editableRoles = [];
它将在更新期间存储相关记录的主键。
附加和配置行为
第一种方式是明确指定所有参数
namespace common\models; use antonyz89\ManyToMany\behaviors\ManyToManyBehavior; class User extends ActiveRecord { /** @var int[] */ public $editableRoles = []; /** * @inheritdoc */ public function behaviors() { return [ [ 'class' => ManyToManyBehavior::class, 'autoFill' => true # default is true. If false, you should fill manually with $model->fill() method 'relations' => [ [ // Editable attribute name 'editableAttribute' => 'editableRoles', // Model of the junction table 'modelClass' => UserRole::class, // Name of the column in junction table that represents current model 'ownAttribute' => 'user_id', // Related model class 'relatedModel' => Role::class, // Name of the column in junction table that represents related model 'relatedAttribute' => 'role_id', ], ], ], ]; } }
属性验证
将可编辑属性添加到模型规则中,以进行大量分配。
public function rules() { ['editableRoles', 'required'], ['editableRoles', 'integer'], ['editableRoles', 'each', 'skipOnEmpty' => false, 'rule' => [ 'exist', 'skipOnError' => true, 'targetClass' => Role::class, 'targetAttribute' => ['editableRoles' => 'id'] ]], }
或使用自定义验证器
use antonyz89\ManyToMany\validators\ManyToManyValidator; public function rules() { ['editableRoles', ManyToManyValidator::class], }
验证器检查列表是否为数组,并且仅包含相关模型中呈现的主键。不能在不附加 ManyToManyBehavior
的情况下使用。
添加视图控制
添加控制视图以管理相关列表。不使用扩展时,可以通过多选来完成此操作
<?= $form->field($model, 'editableRoles')->dropDownList(Role::getList(), ['multiple' => true]) ?>
示例 getList()
方法内容(需要放在 User
模型中)
use yii\helpers\ArrayHelper; /** * @return array */ public static function getList() { $models = static::find()->orderBy('name')->asArray()->all(); return ArrayHelper::map($models, 'id', 'name'); }
全局自动填充
默认情况下,所有 ManyToMany 关系在触发 ActiveRecord::EVENT_AFTER_FIND
事件后都会自动填充,但如果你想禁用此功能并手动填充关系
// common\config\bootstrap.php use antonyz89\ManyToMany\behaviors\ManyToManyBehavior; ManyToManyBehavior::$enableAutoFill = false;
并将 autoFill
设置为 true
以在特定模型上启用自动填充
/** * @inheritdoc */ public function behaviors() { return [ [ 'class' => ManyToManyBehavior::class, 'autoFill' => true # default is true. If false, you should fill manually with $model->fill() method 'relations' => [ // ... ], ], ]; }
如果 $enableAutoFill
和 autoFill
都为 false
,你应该调用 $model->fill()
来手动填充关系
<?php // example/_form.php /* @var $this View */ /* @var $model Example */ // fill relations before load the form $model->fill(); ?> <div class="example-form"> <!-- ... -->