Yii 1.1: An easy way to use escopes and CActiveDataProvider

11 followers

Often used scopes to define criteria in our models. This is a very useful feature as it ensures that in any part of application applying the criteria defined by the scope when called it.

Another common situation is the use CActiveDataProvider which accepts as parameter the model name,a CDbCriteria and a CPagination to construct the ActiveDataProvider.

Eg:

$ DataProvider = new CActiveDataProvider ('Post', array ( 
    'criteria' => array ( 
        'Condition' => 'status = 1' 
        'Order' => 'DESC create_time' 
        'With' => array ('author') 
    ) 
    'pagination' => array ( 
        'PageSize' => 20, 
    ) 
));

And if I want to use scopes and simplify a little ...

Extend the class CActiveRecord, creating the file ...protected / components / MyActiveRecord.php.

class MyActiveRecord extends CActiveRecord { 
 
/ ** 
     * 
     * @ Param Criteria $ CDbCriteria 
     * @ Return CActiveDataProvider 
     * / 
    public function getDataProvider($criteria=null, $pagination=null) {
        if ((is_array ($criteria)) || ($criteria instanceof CDbCriteria) )
           $this->getDbCriteria()->mergeWith($criteria);
        $pagination = CMap:: mergeArray (array ('pageSize' => 10), (array) $pagination); 
        return new CActiveDataProvider(__CLASS__, array(
                        'criteria'=>$this->getDbCriteria(),
                        'pagination' => $pagination
        ));
    }
}

Edit the model...

class Post extends MyActiveRecord {
...
}

and now we can use our method getDataProvider.

$ DataProvider = Post::model()->with('author')->active()->getDataProvider(); 
... 
$ DataProvider = Post::model()->with('author')->active()->getDataProvider(array('order'=>'create_time DESC')); 
... 
$ DataProvider = Post::model()->with('author')->active()->getDataProvider(array ('order'=>'create_time DESC'), array('pageSize'=>25));

That's it!

Total 8 comments

#4637 report it
Maurizio Domba Cerin at 2011/07/28 06:20am
@jogasasa21 - more info

Note that it's not the dataprovider/criteria that returns columns not in select!

In your case it's the CGridView that in case when columns are empty reads the table schema and renders the columns headers with all the fields regardless of what fields/data is in the dataprovider...

To prevent this, you need to set the columns() to be displayed in the CGridView...

More info in the forum topic

#4636 report it
jogasa21 at 2011/07/28 05:23am
Selecting columns with 'criteria'

Be advised that using criteria with the select option will not only return the columns you want to have, but will also return the columns that you don't want with empty values.

$myModel = new CActiveDataProvider('anyTable', array(
   'criteria'=>array(
          'select'=>'field1, field4, field5, field6',
          'condition'=> 'field1= :id',
          'params'=> array(':id'=>$givenValue)
       )
));

In this case if you display the results, for example in a CGridView object, you will also see blank columns for the field2 and field3 table fields.

#3623 report it
phtamas at 2011/04/25 01:52am
It can be simpler

CActiveDataProvider's constructor accepts a model instance as its first parameter.

$dataProvider = new CActiveDataProvider(
    Post::model()->with('author')->active()
);
#3489 report it
Nayjest at 2011/04/15 03:39am
Is it a good idea?

I am interested in opinion of Yii core dev-team members, is it a good idea to implement a method in model, that will return DataProvider?

How about adding such method to CActiveRecord in next releases of Yii?

In combination with using named scopes it looks convenient )

#3476 report it
Rafael Garcia at 2011/04/14 12:04pm
Sorry...

Sorry, there was confusion in the translation.

#3462 report it
Dudie Rirkx at 2011/04/14 03:41am
more code!

Also the indentation is wrong:

$ Pagination = CMap:: mergeArray (array ('pageSize' => 10), (array) $ pagination);

Is that supposed to be part of the IF above? Because like this it's not, even though you indented it along with

$ This-> getDbCriteria () -> mergeWith ($ criteria);
#3461 report it
Dudie Rirkx at 2011/04/14 03:38am
code!

And the code errors as well! This is crazy bad:

public function getDataProvider ($ crit = null, $ pagination = null) { 
        if (is_array ($ criteria) | | $ CDbCriteria instanceof Criteria)

I'm pretty sure that's not right...

#3460 report it
Dudie Rirkx at 2011/04/14 03:35am
spelling!

Please fix all the spelling errors! I literally don't understand half.

Leave a comment

Please to leave your comment.

Write new article