2016-09-02 31 views
1

我试图在配置文件和该配置文件中的多个字段(包括语言和特色)之间创建多对多关系。我已经查看了几个实现,并了解有几个扩展,但我需要尽量减少扩展的使用。Yii2中的多对多关系

我已经创建了适当的迁移...这是一个框架,用户表纯粹是为了登录和OAuth ...所以键可以被忽略。正如你可以在我的控制器中看到的那样,我现在还不知道前进的方向。我的语言模型适用于来自此控制器的所有密集目的(由管理后端控制)。什么在工作?如果我对下面的代码进行了一些修改,那么复选框列表将显示与我手动添加到查找表中的正确选中的项目。试图从代码中修改查找表,除非我使用findOne(knownPK)填充$ languageModel,但是这是不可用的,所以我一直无法做到这一点,因为可以选择多个复选框产生一个数组,并且链接命令需要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']); ?> 

回答

0

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

我说这对学生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]); 
}