Yii 1.1: saverbehavior

Allows simple saving of related models
11 followers

SaverBehavior provides two methods:
1. saveWith - which configures models for relational saving
2. relationalSave - which saves models and returns false if any of models has not been saved.
Component saves model inside DB transaction, and it tries to save all models. If saving is not successful component rollbacks transaction.

Requirements

It requires DB engine supporting transactions in the way to get rollbacks working. Also it requires data passed to saveWith method to have correct indexes - i.e. 0,1,2,3 etc.

Usage

See the following code snippet to see how it works.
you should create all models or array of models to be saved, then for the main model you should call saveWith method passing models which needs to be saved with main model, data for those models and the name of the field to save primary/foreign keys. Optional parameter is $processor that should implement "validate" method accepting an array of models. This method will be called to validate an array of related models. For example, if you need verify a sum of payments and each payment is a separate model.

$order = new Order;
$address = new Address;
$user = new User;
$contacts = array(new Contact);
$invoice = new Invoice;
 
if (isset($_POST['Submit'])) {
      $user->saveWith($address, $_POST['Address'], 'addressId');
      $user->saveWith($contacts, $_POST['Contact'], 'userId'); // here we can add additional parameter to validate all models at once
      $order->saveWith($user, $_POST['User'], 'userId');
      $invoice->saveWith($order, $_POST['Order'], 'orderId');
      $invoice->saveWith($user, $_POST['User'], 'userId');
      $invoice->attributes = $_POST['Invoice'];
      if ($invoice->relationalSave()) {
        echo 'True';
      } else {
        echo 'False';
      }
}
   $this->render('create',
      array('order' => $order,
      'user' => $user,
      'invoice' => $invoice,
      'address' => $address,
      'contacts' => $contacts));

To use behavior you should specify path to behavior in the CActiveRecord's method named behaviors:

public function behaviors() {
        return array(
            'SaverBehavior' => array(
                'class' => 'application.components.SaverBehavior'
            ),
        );
    }

Links

  1. http://habrahabr.ru/blogs/yii/118910/ (russian)

Total 5 comments

#4194 report it
sluderitz at 2011/06/15 10:06am
Passing by Reference

The PHP manual reads: There is no reference sign on a function call - only on function definitions. So line 102 should be changed to:

$independent[0]->owner->internalSave($result);
#3803 report it
orkon at 2011/05/09 02:58am
eadvancedarbehavior

As far as I can see eadvancedarbehavior uses afterSave() to save relations data. So if model is not saved due to validation errors afterSave() won't be called and validation of the related models will not occur. Of cource, you can write a code to perform validation of all models before you actually save them. But in saverbehavior I rely on transactions mechanism and all validation is performed when save() method is called. Because saving of the related models does not depends on the afterSave() all models would be validated.

#3801 report it
Asgaroth at 2011/05/08 11:37pm
eadvancedarbehavior

How is it better/diferent from eadvancedarbehavior?

http://www.yiiframework.com/extension/eadvancedarbehavior/

#3792 report it
orkon at 2011/05/08 10:34am
How to add behaviour?

To use behavior you should specify path to behavior in the CActiveRecord's method named behaviors:

public function behaviors() {
        return array(
            'SaverBehavior' => array(
                'class' => 'application.components.SaverBehavior'
            ),
        );
    }
#3790 report it
Dudie Rirkx at 2011/05/08 09:17am
How to add behaviour?

How would you add these behaviours/mixins to an active record class? And where?

Leave a comment

Please to leave your comment.

Create extension