yii2-relation-trait icon indicating copy to clipboard operation
yii2-relation-trait copied to clipboard

record deleted immediately after insert

Open synatree opened this issue 7 years ago • 8 comments

My model is saved, but immediately deleted.

The condition for the DELETE seems to be a value in a column that is NOT a relationship (FK) column.

Thoughts?

synatree avatar Oct 11 '17 21:10 synatree

Ok, this is a follow up for anyone else out there.

So in my model I had two functions:

public function getSites()
{
   return $this->hasMany( Site::className(), ['siteId' => 'siteId']);
}

public function getSitesAlias()
{
    return $this->hasMany( Site::className(), ['siteId' => 'siteId']);
}

For some reason having two identical relations will cause all your new records to be deleted inside saveAll(). I'm not sure if it's a bug, but it certainly feels like one.

synatree avatar Oct 12 '17 15:10 synatree

could you send me sql?

mootensai avatar Oct 17 '17 04:10 mootensai

how to reproduce this issue? It's not happening to me my code

    public function getChildrens()
    {
        return $this->hasMany(\frontend\models\Children::className(), ['father_id' => 'id']);
    }

    public function getChildrensAlias()
    {
        return $this->hasMany(\frontend\models\Children::className(), ['father_id' => 'id']);
    }

mootensai avatar Oct 18 '17 04:10 mootensai

yep...same here... temporarily, i tweak by alter update method

    public function actionUpdate($id)
    {
        .......
        if ($model->loadAll(Yii::$app->request->post()) && $model->saveAll(['draftStatuses'])) {
                // return to view
        }
    }

skip that relation from being update

for more info, @synatree can you provide posted array

kidzen avatar Oct 29 '17 23:10 kidzen

                                if (!$isNewRecord) {
                                    //DELETE WITH 'NOT IN' PK MODEL & REL MODEL
                                    if ($isManyMany) {
                                        // Many Many
                                        $query = ['and', $notDeletedFK];
                                        foreach ($notDeletedPK as $attr => $value) {
                                            $notIn = ['not in', $attr, $value];
                                            array_push($query, $notIn);
                                        }
                                        try {
                                            if ($isSoftDelete) {
                                                $relModel->updateAll($this->_rt_softdelete, $query);
                                            } else {
                                                $relModel->deleteAll($query);
                                            }
                                        } catch (IntegrityException $exc) {
                                            $this->addError($name, "Data can't be deleted because it's still used by another data.");
                                            $error = true;
                                        }
                                    } 

this part delete all data that are not loaded into the model..

How to reproduce:

migration file

    $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';

    $this->createTable('{{%parent}}', [
        'id' => $this->primaryKey(),
        'parent_id' => $this->integer(),
        'name' => $this->string(),
    ], $tableOptions);

    $this->createTable('{{%child_first}}', [
        'id' => $this->primaryKey(),
        'parent_id' => $this->integer(),
        'name' => $this->string(),
    ], $tableOptions);

    $this->createTable('{{%child_second}}', [
        'id' => $this->primaryKey(),
        'parent_id' => $this->integer(),
        'name' => $this->string(),
    ], $tableOptions);

     $j = 1;
        $this->addForeignKey('fk'.$j++,'{{child_first}}','parent_id','{{parent}}','id');
        $this->addForeignKey('fk'.$j++,'{{child_second}}','parent_id','{{parent}}','id');

parent/_form

        echo $form->field($model, 'name')->textInput(['maxlength' => true, 'placeholder' => 'Name']);
    $forms = [
        // [
        //     'label' => '<i class="glyphicon glyphicon-book"></i> ' . Html::encode('Child First'),
        //     'content' => $this->render('_formDraftDocument', [
        //         'row' => \yii\helpers\ArrayHelper::toArray($model->->childFirsts),
        //     ]),
        // ],
        [
            'label' => '<i class="glyphicon glyphicon-book"></i> ' . Html::encode('Child Second'),
            'content' => $this->render('_formChildSecond', [
                'row' => \yii\helpers\ArrayHelper::toArray($model->childSeconds),
            ]),
        ],
    ];
    echo kartik\tabs\TabsX::widget([
        'items' => $forms,
        'position' => kartik\tabs\TabsX::POS_ABOVE,
        'encodeLabels' => false,
        'pluginOptions' => [
            'bordered' => true,
            'sideways' => true,
            'enableCache' => false,
        ],
    ]);

child first are intentionally not been rendered. after update, you will lose child first data/link

kidzen avatar Oct 31 '17 18:10 kidzen

Got the same issue. Fixed with with(relationName) call on model before using saveAll(). Like $model = Client::find()->with('users')->where(["ID"=>Yii::$app->user->identity->client_id])->limit(1)->one();

MadSkillzSpectrum avatar Nov 17 '17 06:11 MadSkillzSpectrum

    public function saveAll($skippedRelations = [])
    {
    ...
                //No Children left
                $relAvail = array_keys($this->relatedRecords);
                $relData = $this->getRelationData();
                $allRel = array_keys($relData);
                $noChildren = array_diff($allRel, $relAvail);
    ...
}

this is the part that check for relation of the model and current form relation that being posted.

imho, this method are not reliable if you are using different view that call the same controller method.

im suggesting that you use hidden input instead of $model->saveAll($relationName) to identify which relations to check for update.

kidzen avatar Nov 27 '17 02:11 kidzen

Is someone still working on this issue? If not, I've to use some other solution.

Fluit avatar Feb 04 '22 10:02 Fluit