Transactional saving of related models

Hi to everyone,

I hope somebody can help me on this one.

I have two models, Profesional and Tramite. The first one represents the data of an agricultural engineer who has to register in a public record, and the second one represents the inscription and future renewals.

So, the two models have to be saved at the same time. No problem with that, I use the same form to collect data from the two models, and save them like this




if ($modelp->validate() && $modelt->validate()) {

    if ($modelp->save()) {

         $modelp->link('tramites', $modelt);

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

    }

}



It works, but I was wondering. Is there a form to undo the insert of the first model, if for some circunstance, the insert of the second one fail? Is this doable with AR or I should use queries in order to perform a transaction?

Thanks in advance

there are many articles on yii forums and wiki covering this particular topic

http://www.yiiframework.com/doc/guide/1.1/en/form.table

http://www.yiiframework.com/wiki/559/tabular-input-validating-and-saving-related-models/

If you use MySQL and InnoDB engine, why don’t you use db transaction? Below is my example when using it,




if ($model->validate()) {

                $transaction = Yii::app()->db->beginTransaction();


                try {

                    $valid = $model->save();


// Create periodes as well

                    $periodesArr = array('Saldo Awal', 'Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember');


                    foreach ($periodesArr as $i => $curr) {

                        if ($valid) {

                            $newPeriode = new Periode;

                            $newPeriode->financialYearFk = $model->id;

                            $newPeriode->name = $curr . ' ' . $model->name;

                            $newPeriode->code = $model->name . '-' . str_pad($i, 2, 0, STR_PAD_LEFT);

                            $newPeriode->postingStatus = Periode::INACTIVE;

                            $newPeriode->save();

                            if (!$newPeriode->save()) {

                                $valid = false;

                            }

                        }

                    }


                    if ($valid) {

                        $transaction->commit();


                        Yii::app()->user->setFlash('success', array('title' => 'Tambah financial year', 'text' => "$model->name telah berhasil dibuat."));

                        $this->redirect(array('view', 'id' => $model->id));

                    } else {

                        throw new Exception('Gagal dalam membuat financial year beserta periodenya!');

                    }

                } catch (Exception$e) {

                    $transaction->rollBack();

                    Yii::app()->user->setFlash('error', array('title' => 'Tambah financial year', 'text' => "Gagal dalam membuat periode untuk financial year baru!"));

                }

...



Yes, but I wasn’t asking how to save related models, I already have that cover, as you can see in my original question. The question was about the posibility of using transactions with AR, to do a rollback if the insert of the child fails, so it won’t be a father without it’s correspondent child.

It works, Thanks!

@victor I pasted those links as one of them cover transactions I am not sure if you had a look at the articles

Sorry, I didn’t look at the second one. I wonder if there is an equivalent of EAdvancedArBehavior for Yii2. I will have to do a little research. Thanks!