dfware / ar-linkmany
为Yii2 ActiveRecord中的多对多关系保存提供支持
Requires
- yiisoft/yii2: *
This package is auto-updated.
Last update: 2024-09-27 19:55:32 UTC
README
安装此扩展的首选方式是通过composer。
运行
composer require dfware/ar-linkmany
或添加
"dfware/ar-linkmany": "*"
到您的composer.json文件的require部分。
使用方法
此扩展为ActiveRecord的多对多关系保存提供支持。这种支持是通过[[\yii2tech\ar\linkmany\LinkManyBehavior]] ActiveRecord行为提供的。您需要将其附加到您的ActiveRecord类上,并指定目标"has-many"关系
class Item extends ActiveRecord { public function behaviors() { return [ 'linkGroupBehavior' => [ 'class' => LinkManyBehavior::className(), 'relation' => 'groups', // relation, which will be handled 'relationReferenceAttribute' => 'groupIds', // virtual attribute, which is used for related records specification ], ]; } public static function tableName() { return 'Item'; } public function getGroups() { return $this->hasMany(Group::className(), ['id' => 'groupId'])->viaTable('ItemGroup', ['itemId' => 'id']); } }
附加[[\yii2tech\ar\linkmany\LinkManyBehavior]]会在所有者ActiveRecord中添加一个虚拟属性,其名称由[[\yii2tech\ar\linkmany\LinkManyBehavior::$relationReferenceAttribute]]确定。您可以通过此属性指定相关模型的主键
// Pick up related model primary keys: $groupIds = Group::find() ->select('id') ->where(['isActive' => true]) ->column(); $item = new Item(); $item->groupIds = $groupIds; // setup related models references $item->save(); // after main model is saved referred related models are linked
上面的示例等同于以下代码
$groups = Group::find() ->where(['isActive' => true]) ->all(); $item = new Item(); $item->save(); foreach ($groups as $group) { $item->link('groups', $group); }
注意:不要在所有者ActiveRecord类中声明
relationReferenceAttribute
属性。确保它不会与任何现有所有者字段或虚拟属性冲突。
通过relationReferenceAttribute
声明的虚拟属性不仅用于保存,它还包含现有关系的引用
$item = Item::findOne(15); var_dump($item->groupIds); // outputs something like: array(2, 5, 11)
您还可以在保存链接记录的同时编辑现有记录的引用列表
$item = Item::findOne(15); $item->groupIds = array_merge($item->groupIds, [17, 21]); $item->save(); // groups "17" and "21" will be added $item->groupIds = [5]; $item->save(); // all groups except "5" will be removed
注意:如果通过
relationReferenceAttribute
声明的属性从未被用于读取或写入,则它不会在所有者保存时被处理。因此,它不会影响纯粹的所有者保存。
创建关系设置Web界面
[[\yii2tech\ar\linkmany\LinkManyBehavior::$relationReferenceAttribute]]的主要目的是支持创建多对多设置Web界面。您需要做的只是声明ActiveRecord中的此虚拟属性的验证规则,以便可以从请求中收集其值
class Item extends ActiveRecord { public function rules() { return [ ['groupIds', 'safe'] // ensure 'groupIds' value can be collected on `populate()` // ... ]; } // ... }
在视图文件中,您应使用relationReferenceAttribute
属性作为表单输入的属性名
<?php use yii\helpers\ArrayHelper; use yii\helpers\Html; use yii\widgets\ActiveForm; /* @var $model Item */ ?> <?php $form = ActiveForm::begin(); ?> <?= $form->field($model, 'name'); ?> <?= $form->field($model, 'price'); ?> <?= $form->field($model, 'groupIds')->checkboxList(ArrayHelper::map(Group::find()->all(), 'id', 'name')); ?> <div class="form-group"> <?= Html::submitButton('Save', ['class' => 'btn btn-primary']) ?> </div> <?php ActiveForm::end(); ?>
在控制器中,您不需要任何特殊代码
use yii\web\Controller; class ItemController extends Controller { public function actionCreate() { $model = new Item(); if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect(['view']); } return $this->render('create', [ 'model' => $model, ]); } // ... }