Multiple calls of ActiveRecord::model() with criteria

Hi

I do multiple calls to model() to feed into a dataprovider:


            $provider=Data::model()->item($item);

            $dataprovider = new CActiveDataProvider(

                $provider,

                array(

                	'criteria'   => array('order'=>'DATETIME ASC'),

            		'pagination' => array('pageSize'=>$countperpage),

                )

            );



Inside the ‘Data’ class which extends CActiveRecord, we have


    public function item($item) {

		$this->getDbCriteria()->compare('ITEM',$item);

		return $this;

	}

In the second call the compare criteria gets added to the first and hence no more results are returned.

The criteria (as an array) looks like this after the second call:


Criteria .array

(

    'select' => '*'

    'condition' => '(ITEM=:ycp0) AND (ITEM=:ycp1)'

    'params' => array

    (

        ':ycp0' => '100036'

        ':ycp1' => '100038'

    )

    'limit' => -1

    'offset' => -1

    'order' => ''

    'group' => ''

    'join' => ''

    'having' => ''

    'distinct' => false

    'scopes' => null

    'with' => null

    'alias' => null

    'index' => null

    'together' => null

)

You can see that ‘ITEM’ must correspond to two keys.

Am I using ‘model()’ in the wrong way? Is this a bug?

Under the hood the (static) model is fetched from cache, so the criteria are maintained.

I’ve added


 	Data::model()->setDbCriteria(null);

to reset the criteria (which works).

I would expect that ‘Data::model()’ allows me to start with empty criteria without having to do the above trick.

Any suggestion?

you could apply scope in DataProvider’s criteria instead of on model:




'criteria'=>array( 'scopes'=>array( 'item'=>array( $id ) ) ),



I am not sure if this will work, but I think it should. Another solution is:




$provider = Data::model()->item($item);

$criteria = new CDbCriteria();

$provider->applyScopes( $criteria );

//applyScopes will clear scopes/criteria assigned to model and move them to $criteria


$criteria->order = 'DATETIME ASC';


$dataprovider = new CActiveDataProvider( $provider, array(

  'criteria' => $criteria,

  'pagination' => array('pageSize'=>$countperpage),

) );



Hi

Thanks for the feedback.

I made some small trials ending up with:




            $criteria=new CDbCriteria(array('order'=>'DATETIME ASC'));

            /* @var $provider Data*/

            $provider=Data::model()->item($item);

            $provider->applyScopes($criteria);

            $dataprovider = new CActiveDataProvider(

                Data::model(),

                array(

                	'criteria'   => $criteria,

            		'pagination' => array('pageSize'=>$countperpage),

                )

            );

I conclude that the way it works now, the static model should not be used for "scoping" unless the query is "consumed" immediately (for instance with ->findAll() in the same "call").

It looks like applying scopes in the DataProvider criteria is indeed preferable.

[Providing a hint in the documentation about this is surely usefull]