SaverBehavior provides two methods:
- saveWith - which configures models for relational saving
- 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 ¶
- http://habrahabr.ru/blogs/yii/118910/ (russian)
How to add behaviour?
How would you add these behaviours/mixins to an active record class? And where?
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' ), ); }
eadvancedarbehavior
How is it better/diferent from eadvancedarbehavior?
http://www.yiiframework.com/extension/eadvancedarbehavior/
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.
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);
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.