我刚学会了如何使用多个模型创建复杂的表单。
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 :(得分: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,
]);
}