首先,您需要确保声明公司关系的方法对联系人和地址都是正确的。
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,
]);
}
嗨马尔凯,我无法测试你给我的解决方案。我的公司改变了我们使用的框架。但它似乎是正确的做法,我很感谢你帮助我的努力。 – BotLearning