Thats what bugged me for a while too. To solve this, I wrote a behavior that executes cascaded save on all desired child objects:
class CascadeSaveBehavior extends CActiveRecordBehavior
{
public $relations = array();
public function afterSave($event)
{
foreach($this->relations as $relation => $attributes)
{
if($this->Owner->hasRelated($relation))
{
if(is_numeric($relation))
{
$relation = $attributes;
$attributes = array();
}
$objects = $this->Owner->getRelated($relation);
if($objects !== null)
{
foreach($attributes as $attribute => $value)
{
if($value === $this->Owner)
{
$attributes[$attribute] = $this->Owner->id;
}
}
if(is_array($objects))
{
foreach($objects as $object)
{
foreach($attributes as $attribute => $value)
{
$object->setAttribute($attribute, $value);
}
$object->save();
}
}
else
{
foreach($attributes as $attribute => $value)
{
$objects->setAttribute($attribute, $value);
}
$objects->save();
}
}
}
}
return true;
}
}
Usage example:
public function relations()
{
return array(
'sampleRelation' => array(self::HAS_MANY, 'ChildClass', 'parentId')
);
}
public function behaviors()
{
return array(
'CascadeSaveBehavior' => array(
'class' => 'application.components.behaviors.CascadeSaveBehavior',
'relations' => array(
// Here we set the attributes of child elements before saving them.
'sampleRelation' => array('parentId' => $this, 'attribute' => 'value', ...)
)
)
);
}
I think this behavior could be made more complete by automating the setting of foreign keys. At the moment, for ‘has many’ relation foreign key should be specified with ‘foreignKeyField’ => $this. Many other improvements could be made too, I think (like avoid saving objects without changes).