recursive query

Hello yii users.

I am very new in using yii, so please be patient with me.

My question is: is there a built in implementation for recursive queries, or should i try to implement it on the sql level?

I am building a database in wich objects have parent-child relations. There is a small mock table containing 3 relations:




+----------+---------+

|  Parent  |  Child  |

+----------+---------+

|  TEST1   |  TEST2  |

|  TEST1   |  TEST3  |

|  TEST2   |  TEST4  |

+----------+---------+



The obvious result is want to see: if i search for object is child relation with TEST1, i want to see, that also TEST2 has a child object TEST4.

I appreciate your help!

(sorry for my bad english)

There is nothing of prebuild, you should implement on your own.

Try this extension.

Thanks for the info!

I started the implementation, and the recursive search is practicly ready. I have one problem though. Each recursive step is a new query with a new CActiveDataProvider. How can i collect the data from multiple dataproviders, to give over to, let’s say the CListView widget? My searches so far point to the conclusion, that there is no way to “merge” dataproviders.

As a possible solution, you can implement a custom RecursiveDataProvider class and delegate the job of running recursive queries to this class.

I am sure it is my lack of experience, but i don’t really get your advice. Mabe my post wasnt clear enough. Here is a bit of my code:




public function actionRecQuery($dataProvider)

	{

		$temp=$dataProvider->getData();

		

                $i=0;

		while($temp[$i]['childName']){

	

			$condition='parentName='.'"'.$temp[$i]['childName'].'"';

			$dataProvider=new CActiveDataProvider('ViewDepC',array('criteria'=>array('condition'=>$condition,),));

			$i++;

			

			$this->actionRecQuery($dataProvider);

		}

	}



As you can see, the action actionRecQuery is called recursively. Each iteration creates a $dataProvider which is overwritten in the next call. I would like to collect these $dataProviders into one "finalDataProvider" and send it to a viewfile, where i can feed it to a CListView widget.

My approach is probably preatty brute, but thats all i have. I await your advice!

Thanks!

I keep recommending nestedsetbehavior, but if you’d like to collect descendant records by recursion i suggest the following:

No need to instantiate a new CActiveDataProvider on every query. You can use ViewDepC::model()->findAllByAttributes() to retrieve all children of a parent, and collect all records (parents and all of their descendants) in a simple array by using array_merge(). When done, instantiate a CArrayDataProvider with this array and pass it to CListView. Don’t forget to cache the result because - as you probably know - this approach can lead to a large number of queries on every request.

Using findallByAttributes, i array_merged the results in a final array. Then i created a CArraydataProvider


$dataProvider= new CArrayDataProvider($dataArray);

CListView however doens’t like this dataprovider. It keep looking for the ‘id’ property of the model. I am not sure if the ‘id’ property is burried somewhere in the pregenerated code, or i am missing something very basic. Iam aware, that the CArrayDataProvider constructor can have further parameters, i can’t seem to find a proper documentation for it. What could be the problem?

I am sure my questions are getting vaguer and more annoying, thanks for baring with me!

Hi,

I have no exact idea but I think you can implement it using sql.

As my quest with the recursive query is over, i opened a topic about my dataprovider problems. Thank you for your generous help!