2016-10-04 53 views
1

我在我的Yii2應用兩種型號:Yii2動態形式的行動更新出現錯誤

Racks(rackID,rowID,...) 
    RackObjects(rack_objectID,rackID,objectID,...) 

在我racksController我:

public function actionUpdate($id) 
{ 
    $model = $this->findModel($id); 
    $modelsRackObjects = $model->rackObjects; 

    if ($model->load(Yii::$app->request->post())) { 

     $oldIDs = ArrayHelper::map($modelsRackObjects, 'rack_objectID', 'rack_objectID'); 
     $modelsRackObjects = Racks::createMultiple(RackObjects::classname(), $modelsRackObjects); 
     Racks::loadMultiple($modelsRackObjects, Yii::$app->request->post()); 
     $deletedIDs = array_diff($oldIDs, array_filter(ArrayHelper::map($modelsRackObjects, 'rack_objectID', 'rack_objectID'))); 

     // validate all models 
     $valid = $model->validate(); 
     $valid = Racks::validateMultiple($modelsRackObjects) && $valid; 

     if ($valid) { 
      $transaction = \Yii::$app->db->beginTransaction(); 
      try { 
       if ($flag = $model->save(false)) { 
        if (!empty($deletedIDs)) { 
         Racks::deleteAll(['rackID' => $deletedIDs]); 
        } 
        foreach ($modelsRackObjects as $modelRackObjects) { 
         $modelRackObjects->rackID = $model->rackID; 
         if (! ($flag = $modelRackObjects->save(false))) { 
          $transaction->rollBack(); 
          break; 
         } 
        } 
       } 
       if ($flag) { 
        $transaction->commit(); 
        return $this->redirect(['view', 'id' => $model->rackID]); 
       } 
      } catch (Exception $e) { 
       $transaction->rollBack(); 
      } 
     } 
    } 

    return $this->render('update', [ 
     'model' => $model, 
     'modelsRackObjects' => (empty($modelsRackObjects)) ? [new RackObjects] : $modelsRackObjects 
    ]); 
} 

在我的「機架型號」我有:

public static function createMultiple($modelClass, $multipleModels = []) 
{ 
    $model = new $modelClass; 
    $formName = $model->formName(); 
    $post  = Yii::$app->request->post($formName); 
    $models = []; 

    if (! empty($multipleModels)) { 
     $keys = array_keys(ArrayHelper::map($multipleModels, 'rack_objectID', 'rack_objectID')); 
     $multipleModels = array_combine($keys, $multipleModels); 
    } 

    if ($post && is_array($post)) { 
     foreach ($post as $i => $item) { 
      if (isset($item['rack_objectID']) && !empty($item['rack_objectID']) && isset($multipleModels[$item['rack_objectID']])) { 
       $models[] = $multipleModels[$item['rack_objectID']]; 
      } else { 
       $models[] = new $modelClass; 
      } 
     } 
    } 

    unset($model, $formName, $post); 

    return $models; 
} 

當我更新機架窗體並更改一些rackObjects時,出現此錯誤:

完整性約束衝突 - 警予\ DB \ IntegrityException SQLSTATE [23000]:完整性約束違規:1451無法刪除或更新父行,外鍵約束失敗

什麼是錯誤的,我的行動更新???

我更改了我的代碼感謝this answer,現在當我更新記錄時,子表(rackObjects)重複且舊記錄未被刪除!任何想法?

+0

關係有在關係到機架其他表中的記錄。 – vher2

+0

我知道!但我的問題是如何更改代碼來處理SQLSTATE [23000]異常? –

+0

然後使用級聯刪除,參考這個[http://stackoverflow.com/questions/17248852/cascade-delete-the-child-record-of-the-table](http://stackoverflow.com/questions/17248852/cascade-delete-the-child-record-of-the-table) – vher2

回答

0

deleteAll()不會提高beforeDelete事件。你應該遍歷:

$racks = Rack::findAll(['rackID' => $deletedIDs]); 
foreach($racks as $rack) { 
    $rack->delete(); 
} 

而在Rack模型,假設你有hasManyRackObjects

public function beforeDelete() { 
    if (parent::beforeDelete()) { 
    foreach($this->rackObjects as $rackObj) { 
     $rackObj->delete(); 
    } 
    return true; 
    } else { 
    return false; 
    } 
} 
+0

我添加了你的建議代碼,我的誠信問題解決了!謝謝,但當我更新和更改一些rackObjects記錄沒有改變,並返回查看!什麼是問題? –

+0

也許它已被刪除,因爲它與機架有關。當您刪除機架時,相關的機架對象也將被刪除 – vher2

+0

現在,當我按下更新它是重複的孩子(rackObjects)!我很困惑! –