yii2-relation-trait
yii2-relation-trait copied to clipboard
record deleted immediately after insert
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?
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.
could you send me sql?
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']);
}
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
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
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();
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.
Is someone still working on this issue? If not, I've to use some other solution.