CActiveRelation replaces "with"


(Thuey100) #1

First of all, I apologize if this issue has already been addressed. I haven’t been able to find it.

I have a query similar to the following:


Post::model()->findAll(array(

    'with' => array(

        'comment' => array(

            'scopes' => array(

                'readerScope' => array()

            ),

           'with' => array(

               'author'

            )

        )

    )

));

Where readerScope adds a relation. For example:




public function readerScope()

{

    $this->dbCriteria->mergeWith(array('with' => 'readers'));

    return $this;

}



The scope is more complicated than this, but it gets the basic situation across.

The problem is that ‘readers’ isn’t being included in the query. In fact, during the findAll() process, it gets removed from the “with.” After digging through the Yii source code, this happens because in buildJoinTree of CActiveFinder, it first applies the scopes:




$criteria=$model->getDbCriteria();

$criteria->scopes=$scopes;

$model->beforeFindInternal();

$model->applyScopes($criteria);

...

$relation->mergeWith($criteria,true);



So at this point, “with” contains both ‘readers’ and ‘author’. Then, it calls $relation->mergeWith($options). $options at this point is:




array(

           'scopes' => array(

                'readerScope' => array()

            ),

           'with' => array(

               'author'

            )

)



The problem is that in CActiveRelation, mergeWith doesn’t merge “with”, instead it replaces the “with”:




	public function mergeWith($criteria,$fromScope=false)

	{

		...


		if(isset($criteria['with']))

			$this->with=$criteria['with'];


		...

	}



Since it replaces the “with”, ‘readers’ disappears, and the “with” is back to just containing ‘author’.

Why doesn’t CActiveRelation actually merge the “with” instead of replacing it, and is there a work-around?