Possible bug in STAT relation and defaultScope()

Hello, using the lastest stable release (1.1.3), i have the following situation:

I have a model Customer, in wich I have defined a defaultScope():




class Customer extends CActiveRecord

{

    // SOME CODE ...

    

    public function defaultScope()

    {

        $alias = $this->getTableAlias(false,false); // tested with true, false too

        return array(

            'condition'=>$alias.'.active = 1',

        );

    }



Note: the same scope definition is made for the CustomerPayment model (in fact a I have a base class for all my ActiveRecord, in wich I define the defaultScope only once!)

And a STAT relation:




    public function relations()

    {

        // NOTE: you may need to adjust the relation name and the related

        // class name for the relations automatically generated below.

        return array(

            // Other relations ...

            'qtyCustomerPayments'=>array(self::STAT, 'CustomerPayment','idCustomer','defaultValue'=>0),

        );

    }



Then in my controller:




class CustomerController extends Controller

{

    // Some code ...

    public function actionView()

    {

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

            'model'=>$this->loadModel(),

        ));

    }



And finally, my view:




<?php

<h1>Customer: <?php echo $model->code; ?></h1>


<?php $this->widget('zii.widgets.CDetailView', array(

    'data'=>$model,

    'attributes'=>array(

        'code',

        'name',

        'qtyCustomerPayments',

    ),

)); ?>




But this gives me the following error:




CDbException

Description


CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 't.active' in 'where clause'

Source File


C:\wamp\www\yii\framework\web\helpers\CHtml.php(1657)


01645:      * "$model['author']['firstName']".

01646:      * @param mixed the model. This can be either an object or an array.

01647:      * @param string the attribute name (use dot to concatenate multiple attributes)

01648:      * @param mixed the default value to return when the attribute does not exist

01649:      * @return mixed the attribute value

01650:      * @since 1.0.5

01651:      */

01652:     public static function value($model,$attribute,$defaultValue=null)

01653:     {

01654:         foreach(explode('.',$attribute) as $name)

01655:         {

01656:             if(is_object($model))

01657: $model=$model->$name;

01658:             else if(is_array($model) && isset($model[$name]))

01659:                 $model=$model[$name];

01660:             else

01661:                 return $defaultValue;

01662:         }

01663:         return $model;

01664:     }

01665: 

01666:     /**

01667:      * Generates a valid HTML ID based the name.

01668:      * @return string the ID generated based on name.

01669:      */


Stack Trace


#0 C:\wamp\www\yii\framework\db\CDbCommand.php(266): CDbCommand->queryInternal('fetchAll', 2, Array)

#1 C:\wamp\www\yii\framework\db\ar\CActiveFinder.php(1381): CDbCommand->queryAll()

#2 C:\wamp\www\yii\framework\db\ar\CActiveFinder.php(1315): CStatElement->queryOneMany()

#3 C:\wamp\www\yii\framework\db\ar\CActiveFinder.php(459): CStatElement->query()

#4 C:\wamp\www\yii\framework\db\ar\CActiveFinder.php(217): CJoinElement->lazyFind(Object(Customer))

#5 C:\wamp\www\yii\framework\db\ar\CActiveRecord.php(240): CActiveFinder->lazyFind(Object(Customer))

#6 C:\wamp\www\yii\framework\db\ar\CActiveRecord.php(108): CActiveRecord->getRelated('qtyCustomerPayments')

#7 C:\wamp\www\yii\framework\web\helpers\CHtml.php(1657): CActiveRecord->__get('qtyCustomerPayments')

#8 C:\wamp\www\yii\framework\zii\widgets\CDetailView.php(219): CHtml::value(Object(Customer), 'qtyCustomerPayments')

#9 C:\wamp\www\yii\framework\web\CBaseController.php(166): CDetailView->run()

#10 C:\wamp\www\stockcontrolweb\protected\views\cliente\view.php(25): CBaseController->widget('zii.widgets.CDe...', Array)

#11 C:\wamp\www\yii\framework\web\CBaseController.php(119): require('C:\wamp\www\sto...')

#12 C:\wamp\www\yii\framework\web\CBaseController.php(88): CBaseController->renderInternal('C:\wamp\www\sto...', Array, true)

#13 C:\wamp\www\yii\framework\web\CController.php(798): CBaseController->renderFile('C:\wamp\www\sto...', Array, true)

#14 C:\wamp\www\yii\framework\web\CController.php(739): CController->renderPartial('view', Array, true)

#15 C:\wamp\www\stockcontrolweb\protected\controllers\ClienteController.php(59): CController->render('view', Array)

#16 C:\wamp\www\yii\framework\web\actions\CInlineAction.php(32): ClienteController->actionView()

#17 C:\wamp\www\yii\framework\web\CController.php(300): CInlineAction->run()

#18 C:\wamp\www\yii\framework\web\filters\CFilterChain.php(129): CController->runAction(Object(CInlineAction))

#19 C:\wamp\www\yii\framework\web\filters\CFilter.php(41): CFilterChain->run()

#20 C:\wamp\www\yii\framework\web\CController.php(1049): CFilter->filter(Object(CFilterChain))

#21 C:\wamp\www\yii\framework\web\filters\CInlineFilter.php(59): CController->filterAccessControl(Object(CFilterChain))

#22 C:\wamp\www\yii\framework\web\filters\CFilterChain.php(126): CInlineFilter->filter(Object(CFilterChain))

#23 C:\wamp\www\yii\framework\web\CController.php(283): CFilterChain->run()

#24 C:\wamp\www\yii\framework\web\CController.php(257): CController->runActionWithFilters(Object(CInlineAction), Array)

#25 C:\wamp\www\yii\framework\web\CWebApplication.php(324): CController->run('view')

#26 C:\wamp\www\yii\framework\web\CWebApplication.php(121): CWebApplication->runController('custome/view')

#27 C:\wamp\www\yii\framework\base\CApplication.php(135): CWebApplication->processRequest()

#28 C:\wamp\www\stockcontrolweb\index.php(12): CApplication->run()

#29 {main}



Obiously, both Customer and CustomerPayment have a ‘active’ field in the respectives tables (in fact, all my tables have this field…)

For more info, here is the query generated, taken from the log:




2010/07/27 09:09:37 [error] [system.db.CDbCommand] Error in querying SQL: SELECT `idCustomer` AS `c`, COUNT(*) AS `s` FROM `customer_payment` WHERE ( t.active = 1 ) AND (`customer_payment`.`idCustomer`=1) GROUP BY `idCustomer`



I’m doing something wrong?

First thing that I notice is that you don’t have a table with the alias t… so t.active does not exist…

‘t’ is the value returned by getTableAlias(…).

so the default scope finally returns ‘t.active = 1’

The problem here, IMHO, is that, in the generated query, no alias is specified, but, I think it is a bug, because I’m usin defaultScope for all my model, but when a STAT realtion is involved, the generated query is wrong…

Al other querys onvolving BELONG_TO, or HAS_MANY are correctluy generaded… STAT ones not…

By the SQL query you posted seems that for the STAT relation query Yii don’t use the t alias (Quiang?)…

Maybe if you try the alias option for the STAT relation… (I’m thinking aloud)…

I try the alias of the STAT realtion… but




CException

Description


Property "CStatRelation.alias" is not defined.



This is why I say it’s a bug…

I mean to use the alias="…" in the relation declaration…

As it says here… http://www.yiiframework.com/doc/api/CActiveRelation#alias-detail

but the problem is that getTableAlias() returns the alias of the customer table… not of the relation table CustomerPayment…

I know…

that is my realtions method with the alias property added, but this gives me the error i’ve posted…




public function relations()

{

   // NOTE: you may need to adjust the relation name and the related

   // class name for the relations automatically generated below.

   return array(

      // Other relations ...

      'qtyCustomerPayments'=>array(self::STAT, 'CustomerPayment','idCustomer','defaultValue'=>0,'alias'=>'someName'),

   );

}



In fact, CStatRelation extend CBaseActiveRelation… none has an alias property…

Qiang?

Dev team?