2016-10-04 7 views
1

を取得:私のracksControllerでYii2ダイナミックアクションの更新を構成するには、私は私のYii2アプリケーションで二つのモデル持っエラー

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

を私が持っている:

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 
    ]); 
} 

そして、私が持っている私の「ラックモデル」で:

私はラックのフォームを更新し、私はこのエラーを取得するいくつかのrackObjectsを変更
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; 
} 

整合性制約違反 - のYii \ DB \ IntegrityException SQLSTATE [23000]:整合性制約違反:1451は、削除または親行を更新できません:外部キー制約が失敗した

自分の行動のアップデートで何が間違っています?

this answerのコードを変更しました。レコードを更新すると、複製された子テーブル(rackObjects)が複製され、古いレコードは削除されませんでした。何か案が?

+0

hasMany関係を持っていると仮定すると、

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

そしてRackモデルに:あなたはループを通る必要があります。 – 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-table-of-the-table) – vher2

答えて

0

deleteAll()は、beforeDeleteイベントを発生させません。あなたがラックに関連している他のテーブルのレコードがありますRackObjects

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

あなたの提案コードを追加し、私の完全性の問題を解決!ありがとうございますが、私が更新していくつかのrackObjectsレコードを変更しても、何も変わっておらず、表示に戻ってきました問題は何ですか? –

+0

Racksに関連しているため既に削除されている可能性があります。ラックを削除すると、関連するラックオブジェクトも削除されます – vher2

+0

そして、私がアップデートを押すと、それは重複する子(rackObjects)です!私は混乱しています! –

関連する問題