CActiveFinder bug ?




    $criteria=new CDbCriteria;

    $criteria->condition='products_info.language_id=:languageID';

    $criteria->params=array( ':languageID' => $this->_lang_id );

    $criteria->order = 'products_info.products_id ASC';


    $result_limit = count( $products_models = Products::model()->with(

'products_info', 'products_content' )->findAll( $criteria ) );


    $pages=new CPagination( $result_limit );

    $pages->pageSize=self::PAGE_SIZE;

    $pages->applyLimit($criteria);


    print_r( $products_models = Products::model()->with( 'products_info',

'products_content' )->findAll( $criteria )) ;



the first time findAll it works ,

then after $pages=new CPagination( $result_limit );

it always fails

so I found the find method of class CJoinElement losts

if($this->_finder->baseLimited===null)

I add this line, it will always work

this is bug???

no body get the same errors ?

What is the error did you see? Could you please show the call stack if available?




Stack Trace


#0 /usr/local/www/apache22/data/yii-1.1/framework/db/CDbCommand.php(265): CDbCommand->queryInternal('fetchAll', 2, Array)

#1 /usr/local/www/apache22/data/yii-1.1/framework/db/ar/CActiveFinder.php(704): CDbCommand->queryAll()

#2 /usr/local/www/apache22/data/yii-1.1/framework/db/ar/CActiveFinder.php(396): CJoinElement->runQuery(Object(CJoinQuery))

#3 /usr/local/www/apache22/data/yii-1.1/framework/db/ar/CActiveFinder.php(73): CJoinElement->find(Object(CDbCriteria))

#4 /usr/local/www/apache22/data/yii-1.1/framework/db/ar/CActiveFinder.php(101): CActiveFinder->query(Object(CDbCriteria), true)

#5 /usr/local/www/apache22/data/yii-1.1/trial/protected/modules/admin/controllers/ProductsController.php(55): CActiveFinder->findAll(Object(CDbCriteria))

#6 /usr/local/www/apache22/data/yii-1.1/framework/web/actions/CInlineAction.php(32): ProductsController->actionList()

#7 /usr/local/www/apache22/data/yii-1.1/framework/web/CController.php(300): CInlineAction->run()

#8 /usr/local/www/apache22/data/yii-1.1/framework/web/filters/CFilterChain.php(129): CController->runAction(Object(CInlineAction))

#9 /usr/local/www/apache22/data/yii-1.1/framework/web/filters/CFilter.php(41): CFilterChain->run()

#10 /usr/local/www/apache22/data/yii-1.1/framework/web/CController.php(983): CFilter->filter(Object(CFilterChain))

#11 /usr/local/www/apache22/data/yii-1.1/framework/web/filters/CInlineFilter.php(59): CController->filterAccessControl(Object(CFilterChain))

#12 /usr/local/www/apache22/data/yii-1.1/framework/web/filters/CFilterChain.php(126): CInlineFilter->filter(Object(CFilterChain))

#13 /usr/local/www/apache22/data/yii-1.1/framework/web/CController.php(283): CFilterChain->run()

#14 /usr/local/www/apache22/data/yii-1.1/framework/web/CController.php(257): CController->runActionWithFilters(Object(CInlineAction), Array)

#15 /usr/local/www/apache22/data/yii-1.1/framework/web/CWebApplication.php(320): CController->run('list')

#16 /usr/local/www/apache22/data/yii-1.1/framework/web/CWebApplication.php(120): CWebApplication->runController('admin/products/...')

#17 /usr/local/www/apache22/data/yii-1.1/framework/base/CApplication.php(135): CWebApplication->processRequest()

#18 /usr/local/www/apache22/data/yii-1.1/trial/index.php(11): CApplication->run()

#19 {main}




I check framework/db/ar/CActiveFinder.php


public function find of CJoinElement class

Yii 1.1 is different from 1.0.

In Yii 1.1


    if($this->_parent===null) // root element

    {

      $query=new CJoinQuery($this,$criteria);

      $this->_finder->baseLimited=($criteria->offset>=0 || $criteria->limit>=0);

      $this->buildQuery($query);

      $this->_finder->baseLimited=false;

      $this->runQuery($query);

    }

In Yii 1.0


    if($this->_parent===null) // root element

    {

      $query=new CJoinQuery($this,$criteria);

      if($this->_finder->baseLimited===null)

        $this->_finder->baseLimited=($criteria->offset>=0 || $criteria->limit>=0);

      $this->buildQuery($query);

      $this->runQuery($query);

    }

Does it miss


if($this->_finder->baseLimited===null)

in Yii 1.1 ???

with chinese detail

我的action 如下




    $criteria=new CDbCriteria;

    $criteria->condition='products_info.language_id=:languageID';

    $criteria->params=array( ':languageID' => $this->_lang_id );

    $criteria->order = 'products_info.products_id ASC';


    $result_limit = count( $products_models = Products::model()->with( 'products_info', 'products_content' )->findAll( $criteria ) );


    $pages=new CPagination( $result_limit );

    $pages->pageSize=self::PAGE_SIZE;

    $pages->applyLimit($criteria);


    $products_models = Products::model()->with( 'products_info', 'products_content' )->findAll( $criteria );

    $this->render('list', array( 'products_models' => $products_models,'pages'=>$pages, ) );

  }

我發現只要經過$page 後 就會發生這個錯誤

仔細的debug後,發現是在Yii 1.1 中少了


if($this->_finder->baseLimited===null)

這個判斷

我不確定少了這行是不是有特別的原因 ~

還是說我上面的action 的用法有誤~

感謝qiang

What is the error message?

the complete error msg

query log

What’s the relationship between products and products_info, products and products_content?

Note that if their relationship is HAS_MANY, then the above behavior is expected. Because one product can have multiple products_info, if we join them together with limit, then the result will not be correct.

could you tell me how can i fix the problem ??

or I need to read what document ?

The relationship is

What I am asking is how you declare relations() in your products model. As I said, if you declare them to be HAS_MANY, then theoretically the result of joining all three tables together with limit will give you wrong answer. If you are sure this won’t give you problem, you may use products::model()->with(…)->together()->findAll() to force them to join together.

OK, I see ^^

Thanks