Yii2中的多对多关系

Yii2中的多对多关系,yii2,many-to-many,Yii2,Many To Many,我试图在一个概要文件和该概要文件中的几个字段(包括语言和专业)之间创建多对多关系。我已经研究了几个实现,并了解到有几个扩展,但我需要尽量减少扩展的使用 我已经创建了正确的迁移…这是一个框架,用户表纯粹用于登录和OAuth…因此可以忽略键。正如你在我的控制器中看到的,我现在真的不知道前进的方向。我的语言模型是从这个控制器(它由一个管理后端控制)静态的。什么在起作用?如果我对下面的代码做了一些修改,那么复选框列表将显示我手动添加到查找表中的正确选中项。试图从代码中修改查找表,除非我用findOne(

我试图在一个概要文件和该概要文件中的几个字段(包括语言和专业)之间创建多对多关系。我已经研究了几个实现,并了解到有几个扩展,但我需要尽量减少扩展的使用

我已经创建了正确的迁移…这是一个框架,用户表纯粹用于登录和OAuth…因此可以忽略键。正如你在我的控制器中看到的,我现在真的不知道前进的方向。我的语言模型是从这个控制器(它由一个管理后端控制)静态的。什么在起作用?如果我对下面的代码做了一些修改,那么复选框列表将显示我手动添加到查找表中的正确选中项。试图从代码中修改查找表,除非我用findOne(knownPK)填充$languageModel,否则我无法这样做,但是这是不可用的,因为可以选择多个复选框,从而生成一个数组,并且link命令需要单一的ActiveRecordInterface。理想情况下,我只想使用

     $languageModel->load(Yii::$app->request->post(),$trainerModel->formName());
但这是行不通的

此外,框架中是否有删除查找的机制,或者是手动完成的机制。任何帮助或见解都会有所帮助。先谢谢你

  public function safeUp()
 {
     $this->createTable('student', [
        'id'                 => $this->primaryKey(),
        'user_id'            => $this->integer()->notNull(),
    ]);

     $this->createTable('language', [
        'id'                 => $this->primaryKey(),
        'language' => $this->string(63),
    ]);

    $this->createTable('student_language',[
        'id'                 => $this->primaryKey(),
        'language_id' => $this->integer(),
        'student_id'  => $this->integer()
    ]);

      $this->addForeignKey('fk-student-language-language', 'student_language', 'language_id', 'language', 'id', 'CASCADE', 'CASCADE');
      $this->addForeignKey('fk-student-language-student', 'student_language', 'student_id', 'student', 'id', 'CASCADE', 'CASCADE');
      $this->addForeignKey('fk-student-user-user_id', 'student', 'user_id', 'user', 'id', 'CASCADE', 'CASCADE');
   }
我的学生活跃记录

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

public function getLanguages(){
    return $this->hasMany(Language::className(),['id'=>'language_id'])->viaTable('student_language',['student_id'=>'id']);
}
我的语言模型

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

public function getLanguages(){
    return $this->hasMany(student::className(),['id'=>'student_id'])->viaTable('student_language',['language_id'=>'id']);
}
我的控制器

 public function actionProfile()
{
    if (Yii::$app->user->isGuest) {
        throw new UnauthorizedHttpException('This page requires you to be logged in');
    } else {
        $user_id = Yii::$app->user->identity->getId();
        $studentModel = $this->findstudentModelByUserId($user_id);
        if (is_null($studentModel)) {
            $studentModel = new student();
            $studentModel->setAttribute('user_id', $user_id);
            $studentModel->save();
        }

    $languageModel = ??????????????????


        $studentModel->load(Yii::$app->request->post()) && $studentModel->save() && $studentModel->link('languages',$languageModel);

    }

    return $this->render('profile', ['model' => $studentModel]);
}
我的看法

   <?= $form->field($model, 'languages')->checkboxList(\common\models\Language::find()->select(
                        ['language', 'id'])->indexBy('id')->column(),      ['prompt' => 'select Language']); ?>

这是我目前的解决方案,但我有兴趣听到改进。 注意:没有错误检查等,只有功能代码

我将此添加到学生activerecord类中

   public function linkMultiple( $name,Array $models){

    studentLanguage::deleteAll(['student_id' =>$this->id]);

    foreach($models as $model){
        $this->link($name, $model);
    }
    return true;
}
将我的控制器操作修改为以下内容

   public function actionProfile()
{
    if (Yii::$app->user->isGuest) {
        throw new UnauthorizedHttpException('This page requires you to be logged in');
    } else {
        $user_id = Yii::$app->user->identity->getId();
        $studentModel = $this->findstudentModelByUserId($user_id);
        if (is_null($studentModel)) {
            $studentModel = new student();
            $studentModel->setAttribute('user_id', $user_id);
            $studentModel->save();
        }

        $languages = Yii::$app->request->post('student')['languages'];
        $languageModels = Language::findAll($languages);

        $studentModel->load(Yii::$app->request->post()) && $studentModel->save() && $studentModel->linkMultiple('languages',$languageModels);

    }

    return $this->render('profile', ['model' => $studentModel]);
}

这是我目前的解决方案,但我有兴趣听到改进。 注意:没有错误检查等,只有功能代码

我将此添加到学生activerecord类中

   public function linkMultiple( $name,Array $models){

    studentLanguage::deleteAll(['student_id' =>$this->id]);

    foreach($models as $model){
        $this->link($name, $model);
    }
    return true;
}
将我的控制器操作修改为以下内容

   public function actionProfile()
{
    if (Yii::$app->user->isGuest) {
        throw new UnauthorizedHttpException('This page requires you to be logged in');
    } else {
        $user_id = Yii::$app->user->identity->getId();
        $studentModel = $this->findstudentModelByUserId($user_id);
        if (is_null($studentModel)) {
            $studentModel = new student();
            $studentModel->setAttribute('user_id', $user_id);
            $studentModel->save();
        }

        $languages = Yii::$app->request->post('student')['languages'];
        $languageModels = Language::findAll($languages);

        $studentModel->load(Yii::$app->request->post()) && $studentModel->save() && $studentModel->linkMultiple('languages',$languageModels);

    }

    return $this->render('profile', ['model' => $studentModel]);
}