Weird behavior with yii2-relation-trait

Hi, I am a little bit confused…

from now to then yii2 with relation traits acts completly different than assumed…

I build models and CRUD with yii2-enhanced-gii for a table with relations to other tables. The relations are build with IDs as primary keys. yii2-enhanced-gii uses yii2-relation-trait. Until last Friday the "app" worked pretty well, I was able to insert and update records without a mess. The only change was an update with composer to Yii 2.0.7 (from 2.0.6) and yii2-relation-trait to 1.0.9 (from 1.0.8). And I did the manual upgrade steps for 2.0.7 like ICU Data etc.

Until then I noticed, that every time I used the update action, the updated record was not saved but deleted and every related records (from the related tables) were deleted, too!

Here is the generated controller code from gii for actionUpdate (I only added that "can()" stuff for RBAC) :




public function actionUpdate($id)

    {

        $model = $this->findModel($id);

        if (Yii::$app->user->can('updateOwnItem', ['model' => $model])) {

            if ($model->loadAll(Yii::$app->request->post()) && $model->saveAll()) {

                return $this->redirect(['view', 'id' => $model->id]);

            } else {

                return $this->render('update', ['model' => $model,]);

            }

        } else {

            throw new MethodNotAllowedHttpException(Yii::t('app', 'You are not allowed to access this page.'));

        }

    }



Below is the relevant part from yii2-relation-trait: function saveAll(). I numbered it and reduced (…) the parts that are not relevant. I analyzed it with Xdebug and found that in my case it runs straight down to line 10 ($this->save() is true and $this->relatedRecords is empty), so that the "else" part of the if-construct is used ("No children left").

It works as coded, but why the heck do we want to delete the records (line 25 or 35)?!? We are talking about saveAll()…

In my example, the loaded record data in the form wasn’t touched, I just clicked the Update Button (thus calling actionUpdate).

And why did it work so far?!? It just saved/updated the modified form data to table, storing the IDs without deleting the related record in other tables).

I hope you can led me to the light or point me to some docs. The "app" and the example consists just of generated code from gii, modified only for optical enhencments.

I found nothing relevant in the release notes of yii2 2.0.7 or yii2-relation-trait 1.0.9 that could explain the behavior and why it changed "over night".




1    public function saveAll()

2    {

3        /* @var $this ActiveRecord */

4        $db = $this->getDb();

5        $trans = $db->beginTransaction();

6        try {

7            if ($this->save()) {

8                $error = 0;

9                if (!empty($this->relatedRecords)) {...} else {

10                   //No Children left

11                   //echo "No Children left";

12                  if (!$this->isNewRecord) {

13                       $relData = $this->getRelationData();

14                       foreach ($relData as $rel) {

15                           /* @var $relModel ActiveRecord */

16                           if(empty($rel['via'])){

17                               $relModel = new $rel['modelClass'];

18                               $condition = [];

19                               $isManyMany = count($relModel->primaryKey()) > 1;

20                               if($isManyMany){

21                                   foreach ($rel['link'] as $k => $v) {

22                                       $condition[] = $k . " = " . $this->$v;

23                                   }

24                                   try {

25                                       $relModel->deleteAll(implode(" AND ", $condition));

26                                   } catch (\yii\db\IntegrityException $exc) {

27                                       $this->addError($rel['name'], "Data can't be deleted because it's still used by another data.");

28                                       $error = 1;

29                                   }

30                               }else{

31                                   foreach ($rel['link'] as $k => $v) {

32                                       $condition[] = $k . " = " . $this->$v;

33                                   }

34                                   try {

35                                       $relModel->deleteAll(implode(" AND ", $condition));

36                                   } catch (\yii\db\IntegrityException $exc) {

37                                       $this->addError($rel['name'], "Data can't be deleted because it's still used by another data.");

38                                       $error = 1;

39                                   }

40                              }

41                           }

42                       }

43                   }

44               }

46

47               if ($error) {...}

48               $trans->commit();

49               return true;

50           } else {...}

51       } catch (Exception $exc) {...}

52   }



[color="#006400"]/* Moved from "General Discussions" to "Extensions" */[/color]

It looks like the BC issue of yii2-relation-trait 1.0.9.

You may want to report the issue at github.

Indeed, yii2-relation-trait causes my trouble. I switched back to an older version of yii2-relation-trait and it works as expected. thumbs up

I will report it on github…