Saving relation

Coming from J2EE platform and having background with hibernate and JPA it seems wierd to me that I cannot update relation this way:

$parent->child = $child;

$parent->save();

It doesnt persist new relation, instead you have to do:

$parent->child_id = $child->id; (persisted relation)

$parent->child = $child; (online relation)

$parent->save();

Why is this necessary or am I missing something?

Hello,

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).