CActiveDataProvider (many to many and contition)

Hi all :)

I have category and products (many to many)

how i can limit products to particular category with this code:


   $dataProvider=new CActiveDataProvider('Product', array(

     'criteria'=>array(

        'with'=>array('categories'=>array( 'condition'=>'categories.id=' .$category['id'], 'together'=>true)),

         

     ),

     'pagination'=>array(

         'pageSize'=>20,

     ),

     ));


        $this->render('index',array(

			'dataProvider'=>$dataProvider,

		));

	}

Right now its showing all products :(

Where i can find more information about Yii AR?

I have the exact same question. I want to use CActiveDataProvider to fetch objects that are in a certain category. There is a many-to-many relationship between objects and categories.

There is an objects table, categories table, and a mapping table (object_id, category_id).

I have already setup the relations() part for the Object and Category models.

And it works correctly. For example

$obj = Object::model()->findByPk(1);

$category_list = $obj->categories;

$category = Category::model()->findByPk(2);

$obj_list = $category->objects;

$obj_list contains the data that I want.

However, I’d like to get the same data by using CActiveDataProvider.

Is there a way?

You could use a INNER JOIN:


'with'=>array('categories'=>array( 

   'on'=>'categories.id=' .$category['id'], 

   'together'=>true,

   'joinType'=>'INNER JOIN', 

)),

Eventually, I found a solution which was documented here:

http://www.yiiframework.com/forum/index.php?/topic/7420-undestanding-relational-queries-with-cactivedataprovider/

(1) I created a class which extended CActiveDataProvider. It adds a member variable named "together".




class MyDataProvider extends CActiveDataProvider

{

        public $together = false;


        /**

         * Fetches the data from the persistent data storage.

         * @return array list of data items

         */

        protected function fetchData()

        {

                $criteria=clone $this->getCriteria();

                if(($pagination=$this->getPagination())!==false)

                {

                        $pagination->setItemCount($this->getTotalItemCount());

                        $pagination->applyLimit($criteria);

                }

                if(($sort=$this->getSort())!==false)

                        $sort->applyOrder($criteria);


                if ($this->together)

                {

                        return CActiveRecord::model($this->modelClass)->with($criteria->with)->together()->findAll($criteria);

                }

                else

                {

                        return CActiveRecord::model($this->modelClass)->findAll($criteria);

                }

        }


}




  1. The new class file from step #1 needs to be placed in the directory "protected/extensions"

  2. Edit the file "protected/config/main.php" and include the new extension in the "import" field




        'import'=>array(

                'application.models.*',

                'application.components.*',

                'ext.MyDataProvider',

        ),



  1. Modified the controller file to use the new class



          $dataProvider = new MyDataProvider('games',

                            array(

                                  'criteria' => array(

                                      'with' => array(

                                        'categories' => array(

                                            'on' => 'categories.id=' . $category_id,

                                            'joinType'=>'INNER JOIN',)

                                       )

                                  ),

                                  'together'=> true,

                                  'pagination' => array(

                                                        'pageSize' => $page_results,

                                                       ),

                                 )

                          );



  1. Also don’t forget to modify the relations() function for the two models that have the MANY_MANY relationship.

Thx for reply, but i still dont understand why this cant folow KISS rule, why i need to extend class? This is very common task…

he he :lol: , good point!!!

what I want is to be incorporated into the framework

csun thanks! This work!

Great thx for this solution!

[font=arial, sans-serif][size=3]this solution is obsolete![/size][/font]

[font="arial, sans-serif"][size=3]you can use CDbCriteria

[/size][/font][size=3]http://www.yiiframework.com/doc/api/CDbCriteria#together-detail[/size]

Thanks Mike,I was about to engage in this class exteneded solution,but chose to try a Yii Guru’s (like you) snippet first.Worked perfect!

Thanks, it works prefect !