带有外键的模型的 Yii 2.0 视图

Yii 2.0 view for models with foreign keys

我有 3 个 table:

首先table是主要的tableTheSims4Pages。它有一个名为 id 的主键。 第二个 table 是关系 table

CREATE TABLE IF NOT EXISTS `TheSims4PagesCategoriesRelations` (
  `id` int(11) NOT NULL,
  `postId` int(11) NOT NULL,
  `catId` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `TheSims4PagesCategoriesRelations`
  ADD CONSTRAINT `TheSims4PagesCategoriesRelations_ibfk_2` FOREIGN KEY (`catId`) REFERENCES `TheSims4PagesCategories` (`id`),
  ADD CONSTRAINT `TheSims4PagesCategoriesRelations_ibfk_1` FOREIGN KEY (`postId`) REFERENCES `TheSims4Pages` (`id`);

第三个table是TheSims4PagesCategories,PKid.

目前我有模型 TheSims4Pages:

<?php

namespace app\models\TheSims4;

use Yii;

/**
 * This is the model class for table "TheSims4Pages".
 *
 * @property integer $id
 * @property string $pageName
 * @property string $pageEditDate
 * @property integer $isDraft
 * @property integer $authorId
 * @property string $pageText
 *
 * @property SiteUsers $author
 * @property TheSims4PagesCategoriesRelations[] $theSims4PagesCategoriesRelations
 */
class TheSims4Pages extends \yii\db\ActiveRecord {

    /**
     * @inheritdoc
     */
    public static function tableName() {
        return 'TheSims4Pages';
    }

    /**
     * @inheritdoc
     */
    public function rules() {
        return [
            [['pageName', 'authorId', 'pageText'], 'required'],
            [['pageEditDate'], 'safe'],
            [['isDraft', 'authorId'], 'integer'],
            [['pageText'], 'string'],
            [['pageName'], 'string', 'max' => 500],
            [['authorId'], 'exist', 'skipOnError' => true, 'targetClass' => SiteUsers::className(), 'targetAttribute' => ['authorId' => 'id']],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels() {
        return [
            'id' => 'ID',
            'pageName' => 'Page Name',
            'pageEditDate' => 'Page Edit Date',
            'isDraft' => 'Is Draft',
            'authorId' => 'Author ID',
            'pageText' => 'Page Text',
        ];
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getAuthor() {
        return $this->hasOne(SiteUsers::className(), ['id' => 'authorId']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getTheSims4PagesCategoriesRelations() {
        return $this->hasMany(TheSims4PagesCategoriesRelations::className(), ['postId' => 'id']);
    }

}

如何为模型的 getTheSims4PagesCategoriesRelations 使用 select 元素制作 TheSims4Pages 的视图,例如

echo $form->field($model, 'categoryId')->dropDownList($listData);

但是关系 table?

也就是说,我想用 TheSims4PagesCategories table 中的所有类别制作 select 项,并将多个 selection 类别保存到模型中

$model = new TheSims4Pages();

非常感谢!

在视图中:(其中 'categoryName' 是类别 table 中用作标签的列)

<?= $form->field($model, 'categories')
    ->dropDownList(ArrayHelper::map(TheSims4PagesCategories::find()->all(),
        'id',
        'categoryName'
    ), ['multiple'=>'multiple']) ?>

在模型中添加虚拟变量

// ...

class TheSims4Pages extends \yii\db\ActiveRecord {

    public $categories;

    public function rules()
    {
        return [
            ['categories', 'each', 'rule' => ['integer']],
            // your other rules
        ];
    }

    // ...


    public function afterFind()
    {
        parent::afterFind();

        $this->categories = [];

        if (!empty($this->theSims4PagesCategoriesRelations)) {
            foreach ($this->theSims4PagesCategoriesRelations as $cat) {
                $categories[$cat->catId] = $cat->catId;
            }
            $this->categories = $categories;
        }
    }

    /* deleting might work better in afterSave 
       due to ending up with posts without categories on constraint fail
    public function beforeSave($insert)
    {
        parent::beforeSave($insert);

        if ($insert) {
        } else {
            TheSims4PagesCategoriesRelations::deleteAll(['postId' => $this->id]);
        }
    }
    */

    public function afterSave($insert, $changedAttributes)
    {
        parent::afterSave($insert, $changedAttributes);

        if ($insert) {
        } else {
            TheSims4PagesCategoriesRelations::deleteAll(['postId' => $this->id]);
        }

        if ($this->categories) {
            foreach ($this->categories as $cat_id) {
                $relation = new TheSims4PagesCategoriesRelations();
                $relation->postId = $this->id;
                $relation->catId = $cat_id;
                $relation->save();
            }
        }
    }
}