antonyz89/yii2-many-to-many

为 Yii 2 框架提供的多对多 ActiveRecord 关系。由 Alexey Rogachev 创建,AntonyZ89 分支

安装次数: 1,217

依赖项: 1

建议者: 0

安全性: 0

星标: 0

关注者: 3

分支: 16

类型:yii2-extension

0.3.6 2023-08-12 18:07 UTC

This package is auto-updated.

Last update: 2024-09-12 20:18:49 UTC


README

实现 Yii 2 框架的多对多关系

arogachev 创建,AntonyZ89 分支

Latest Stable Version Total Downloads Latest Unstable Version License

安装

通过 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' => [
                // ...
            ],
        ],
    ];
}

如果 $enableAutoFillautoFill 都为 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">
    <!-- ... -->