2017-03-06 113 views
1

我刚刚学会了如何使用多个模型创建复杂表单。从多个表填充表单yii2 mysql

public function actionCreate() 
{ 
    $model = new Company(); 
    $contact = new Contact(); 
    $address = new Address(); 
    $company_contact = new CompanyContact(); 
    $company_address = new CompanyAddress(); 

    if ($model->load(Yii::$app->request->post()) && $contact->load(Yii::$app->request->post()) && $address->load(Yii::$app->request->post())) { 
     $model->save(); 
     $address->save(); 
     $contact->save(); 

     // we need to insert the index from each key to the table Company_Contact to associate them 
     $company_contact->id_company = $model->id_company; 
     $company_contact->id_contact = $contact->id_contact; 

     // same procedure for Company_Address 
     $company_address->id_company = $model->id_company; 
     $company_address->id_address = $address->id_address; 

     $company_address->save(); 
     $company_contact->save(); 

     return $this->redirect(['index']); 
    } else { 
     return $this->render('create', [ 
      'model' => $model, 
      'contact' => $contact, 
      'address' => $address 
     ]); 
    } 
} 

现在的问题是,我不知道怎么回叫每个表中的数据,所以我可以填充自己的状态,之后保存更改。我有使用JOIN的想法,但我没有必要知道如何在yii2框架上进行这项工作。

回答

0

首先,您需要确保声明公司关系的方法对联系人和地址都是正确的。

public function getContact() { 
    return $this->hasOne(Contact::className(), ['id_contact' => 'id_contact']) 
     ->viaTable('Company_Contact', ['id_company' => 'id_company']); 
} 

public function getAddress() { 
    return $this->hasOne(Address::className(), ['id_address' => 'id_address']) 
     ->viaTable('Company_Address', ['id_company' => 'id_company']); 
} 

现在我们知道我们的关系是正确的,我们可以进行一些修改actionCreate()我们的控制器内:

public function actionCreate() { 
    $model = new Company(); 
    $contact = new Contact(); 
    $address = new Address(); 

    // Check if the request was made using post, otherwise skip and render 'create' view 
    if(Yii::$app->request->isPost) { 
     // Begin a transaction, so we only make changes to the Database when we can save all the needed records. 
     $transaction = Company::getDb()->beginTransaction(); 
     try { 
      $post = Yii::$app->request->post(); 

      // We try to load $model, $contact and $address. If we can't then we throw an Exception that will be caught. 
      if(!($model->load(Yii::$app->request->post()) && $contact->load(Yii::$app->request->post()) && $address->load(Yii::$app->request->post()))) { 
       throw new \Exception('Could not load post data to models'); 
      } 

      // Now we try to save them, each by itself. If any of them fail to save then we throw an Exception. 

      if(!$model->save()) { 
       throw new \Exception('Could not save $model'); 
      } 

      if(!$address->save()) { 
       throw new \Exception('Could not save $address'); 
      } 

      if(!$contact->save()) { 
       throw new \Exception('Could not save $contact'); 
      } 

      // Now we populate the relationships. 

      // First parametter is the name of the relationship, Second is the model we want to link to. 
      $model->link('address', $address); 
      $model->link('contact', $contact); 

      // With the relationships correctly declared, we don't need to populate the juncture table ourselves, just link both models. 
      // If the 'link' method cannot link the models, then it will throw an Exception that will be caught. 

      // If we managed to save all the records and link them, now we commit the transaction so the changes made in the database are not reverted. 
      $transaction->commit(); 

      return $this->redirect(['index']); 
     } 
     catch(\Exception $e) { 
      // If there are any problems then we will do a rollBack to the transaction, reverting the changes made during the transaction. 
      $transaction->rollBack(); 
     } 
    } 

    return $this->render('create', [ 
     'model' => $model, 
     'contact' => $contact, 
     'address' => $address, 
    ]); 
} 

而现在actionUpdate我们只需要得到$ ID将被用作PK寻找公司。

public function actionUpdate(&id) { 
    $model = Company::findOne($id); 

    // If $model is null, then throw a NotFoundHttpException. 
    if($model === null) { 
     throw new \yii\web\NotFoundHttpException('The requested page does not exist.'); 
    } 

    // We can get the $contact and $address models by using the relationships we already declared. 
    $contact = $model->contact; 
    $address = $model->address; 

    // Now we don't need to change much from actionCreate, 
    // except we don't need to link $model with $contact or $address because they are already linked, 
    // we just need to save changes made to them. 
    if(Yii::$app->request->isPost) { 
     $transaction = Company::getDb()->beginTransaction(); 
     try { 
      $post = Yii::$app->request->post(); 

      if(!($model->load(Yii::$app->request->post()) && $contact->load(Yii::$app->request->post()) && $address->load(Yii::$app->request->post()))) { 
       throw new \Exception('Could not load post data to models'); 
      } 

      if(!$model->save()) { 
       throw new \Exception('Could not save $model'); 
      } 

      if(!$address->save()) { 
       throw new \Exception('Could not save $address'); 
      } 

      if(!$contact->save()) { 
       throw new \Exception('Could not save $contact'); 
      } 

      $transaction->commit(); 

      return $this->redirect(['index']); 
     } 
     catch(\Exception $e) { 
      $transaction->rollBack(); 
     } 
    } 

    return $this->render('update', [ 
     'model' => $model, 
     'contact' => $contact, 
     'address' => $address, 
    ]); 
} 
+0

嗨马尔凯,我无法测试你给我的解决方案。我的公司改变了我们使用的框架。但它似乎是正确的做法,我很感谢你帮助我的努力。 – BotLearning