Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

record deleted immediately after insert #48

Open
synatree opened this issue Oct 11, 2017 · 8 comments
Open

record deleted immediately after insert #48

synatree opened this issue Oct 11, 2017 · 8 comments

Comments

@synatree
Copy link

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
Copy link
Author

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.

@mootensai
Copy link
Owner

could you send me sql?

@mootensai
Copy link
Owner

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

@kidzen
Copy link

kidzen commented Oct 29, 2017

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
Copy link

kidzen commented Oct 31, 2017

                                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

@MadSkillzSpectrum
Copy link

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();

@kidzen
Copy link

kidzen commented Nov 27, 2017

    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.

@Fluit
Copy link

Fluit commented Feb 4, 2022

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants