Overriden $Limit Condition In Scopes

Hi there,

I have following scope:




	public function allowedPhotoAdsL1($limit=-1)

	{

		$this->getDbCriteria()->mergeWith(array(

			'condition'=>'type=:photo_ad and status IN(:verified,:active) and leaf = 1',

			'params'=>array(

				':verified'=>Advert::Verified,

				':active'=>Advert::Active,

				':photo_ad'=>Advert::Photo_Ad,

			),

			'order'=>"rand()",

			'limit'=>$limit,

		));

		return $this;

	}



In controller call that as this:




$L1 = Advert::model()->allowedPhotoAdsL1($limit)->findAll();



If value of $limit variable is equal to 0, limit condition in scope don’t act! and all exist records returned!

I want when $limit value was 0, records not returned.

what’s the problem?

Ho I think you can pass a wrong limit on function


 public function allowedPhotoAdsL1($limit=0){}

What is your backing database? Because [font="Courier New"]LIMIT -1[/font] makes absolutely no sense in MySQL.

I tried your way, but don’t work. meanwhile i want when $limit will not set, all records returned.

ok try this


 public function allowedPhotoAdsL1($limit){

  if($limit == '0'){

    $limit =0;

  }else{

    $limit = $limit

  }


 }

I am not sure it’s work or not.

Hi,

if the $limit not set then you shouldn’t include in your criteria so


 public function allowedPhotoAdsL1($limit=null)

        {

                $r = array(

                        'condition'=>'type=:photo_ad and status IN(:verified,:active) and leaf = 1',

                        'params'=>array(

                                ':verified'=>Advert::Verified,

                                ':active'=>Advert::Active,

                                ':photo_ad'=>Advert::Photo_Ad,

                        ),

                        'order'=>"rand()",

                );




if ($limit != null) $r = array_merge($r,array('limit'=>$limit));




$this->getDbCriteria()->mergeWith($r);


                return $this;

        }

I think it’s a bug in CDbCriteria::mergeWith.

http://www.yiiframework.com/doc/api/1.1/CDbCriteria#mergeWith-detail

The line 523, 524 of CDbCriteria.php reads:

But it should be




		if($criteria->limit>=0)

			$this->limit=$criteria->limit;



I agree with softark there is a bug!

So the solution at the moment is the insertion or not of the limit… or using a trick value $limit < 0 like -1 …

MySQL

There is a confusing between database and Yii definition about limit

in database




limit>0 means some results

limit=0 means no results

limit<0 no sense in sql

Yii (at the moment)


limit>0 means some results

limit<=0 means all results

So there is no way in current version in Yii to set limit using a value and returns ‘no result’ unless not set limit

I think you can write like this at the moment:




	public function allowedPhotoAdsL1($limit=-1)

	{

		$this->getDbCriteria()->mergeWith(array(

			'condition'=>'type=:photo_ad and status IN(:verified,:active) and leaf = 1',

			'params'=>array(

				':verified'=>Advert::Verified,

				':active'=>Advert::Active,

				':photo_ad'=>Advert::Photo_Ad,

			),

			'order'=>"rand()",

			// 'limit'=>$limit,

		));

		if ($limit >= 0)

			$this->criteria->limit = $limit;


		return $this;

	}



The bug seems to reside only in CDbCriteria::mergeWith. The other parts of the db related methods should distinguish "0"(limit = 0) and "<0"(no limit) correctly.

Thanks, but with following command all records returned.




$L1 = Advert::model()->allowedPhotoAdsL1(0)->findAll();



I want when parameter set to 0 not return any records! The allowedPhotoAdsL1 is as the same you defined.

[quote=“softark, post:11, topic:64992”]

I think you can write like this at the moment:




	public function allowedPhotoAdsL1($limit=-1)

	{

		$this->getDbCriteria()->mergeWith(array(

			'condition'=>'type=:photo_ad and status IN(:verified,:active) and leaf = 1',

			'params'=>array(

				':verified'=>Advert::Verified,

				':active'=>Advert::Active,

				':photo_ad'=>Advert::Photo_Ad,

			),

			'order'=>"rand()",

			// 'limit'=>$limit,

		));

		if ($limit >= 0)

			$this->criteria->limit = $limit;


		return $this;

	}



Error:


Property "Advert.criteria" is not defined.	

Ok then, use this one


public function allowedPhotoAdsL1($limit=null)

        {

if ($limit !== 0) {

                $r = array(

                        'condition'=>'type=:photo_ad and status IN(:verified,:active) and leaf = 1',

                        'params'=>array(

                                ':verified'=>Advert::Verified,

                                ':active'=>Advert::Active,

                                ':photo_ad'=>Advert::Photo_Ad,

                        ),

                        'order'=>"rand()",

                );

} else {

 $r = array('condition'=>'0 = 1')

}


if ($limit != null) $r = array_merge($r,array('limit'=>$limit));




$this->getDbCriteria()->mergeWith($r);


                return $this;

 }

Or in your first code add


if ($limit == 0) $this->getDbCriteria()->addCondition('0=1');

Thanks dear friend & other friends, solved.