2017-03-06 5 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

関連する問題