$model->unsetAttribute() not nullify virtual attribute value

Dear All,

I am using ERememberFilterGridView extension, but this question is actually very general concept (I think!)

When calling $model->unsetAttribute(), it is not nullify the value of virtual attribute. The context is that I have a FormHeader object with relation to Partner object. The field in FormHeader is partnerFk. Since, I use partner to store customer and supplier and also FormHeader is used to store Sales and Purchase, I have virtual attribute called customer and supplier in FormHeader. Both virtual attributes are put on safe rules.

It is true that I use ERememberFilterGridView to keep the search value, but somehow when I reset the filter, using $model->unsetAttributes(), the supplier and customer are not null. Still keep the value. Even, when I use rememberscenario to differentiate between different pages (sales and purchase), they are kept the same.

I think unsetAttribute will nullify all values declare in safe rule. Can someone explain more on this?

Thank you in advance.

PS: If, in CgridView, I use partnerFk value, it will be correct, but it will not working if the column name on CGridView is either supplier or customer.

if you don’t send a list of attributes to unsetAttributes() it uses this method (http://www.yiiframew…uteNames-detail) to get a list of attributes. That method returns only the list of fields from the table.

You can solve this by sending a custom list of attributes or by manually setting those virtual attributes to null.

One idea would be to use http://www.yiiframework.com/doc/api/1.1/CModel#getSafeAttributeNames-detail like

[color=#1C2837][size=2]


$model->unsetAttribute($model->getSafeAttributeNames());

[/size][/color]

Thank you for the prompt advice and solution.

I will try it and come back to you soon. If this is work, the other foreseen problem could be the way that ERememberFilter / EButtonColumnWithClearFilter works.

Once again, thank you for the very quick response.

Hi mdomba,

It did not work ;(

I tried to clear the attributes like this,


$model->unsetAttribute($model->getSafeAttributeNames());

or like this,

[code]$model->unsetAttributes(array(‘headerNo’, ‘partnerFk’, ‘formDate’, ‘dueDate’, ‘calcCharges’, ‘calcPayments’, ‘calcBalance’));[code]

Still the same, when refresh, the virtual attributes are not nullify…

the virtual attribute is calcCharges, calcPayments and calcBalance.

The virtual attributes are define in the FormHeader.php as follow,

[code]

public $customer;


public $supplier;


public $partnerName;


public $calcCharges;


public $calcPayments;


public $calcBalance;

[code]

they are also included in safe rules

[code]

array(‘calcCharges, calcPayments, calcBalance, customer, supplier, partnerName, partnerFk, formType, headerNo, formDate, partnerFk, dueDate, referenceNo, truckNo, driver, memo, postingStatus’, ‘safe’, ‘on’ => ‘search’),

[code]

In addition, this is inside my search method:

[code]

    $calcChargesSql = "(SELECT SUM(d.unitPrice * d.quantity) FROM form_detail d WHERE d.headerFk = t.id)";


    $calcPaymentsSql = "(SELECT SUM(p.amount) FROM payment_detail p WHERE p.headerFk = t.id)";


    $calcBalanceSql = "(SELECT (c.totChr - p.totPay) FROM "


            . "(SELECT d.headerFk, SUM(d.unitPrice * d.quantity) AS totChr FROM form_detail d GROUP BY d.headerFk) c LEFT JOIN "


            . "(SELECT pd.headerFk, SUM(pd.amount) AS totPay FROM payment_detail pd GROUP BY pd.headerFk) p ON p.headerFk = c.headerFk WHERE c.headerFk = t.id)";





    $criteria = new CDbCriteria;


    $criteria->with = array('partner');





    // select


    $criteria->select = array(


        '*',


        $calcChargesSql . " AS calcCharges",


        $calcPaymentsSql . " AS calcPayments",


        $calcBalanceSql . " AS calcBalance",


    );





    $criteria->compare($calcChargesSql, MyActiveRecord::changeFormat($this->calcCharges));


    $criteria->compare($calcPaymentsSql, MyActiveRecord::changeFormat($this->calcPayments));


    $criteria->compare($calcBalanceSql, MyActiveRecord::changeFormat($this->calcBalance));

[code]

Any idea? other than set them to null directly?

Still not working Maurizio,

This is inside my FormHeader.php




public $customer;

    public $supplier;

    public $partnerName;

    public $calcCharges;

    public $calcPayments;

    public $calcBalance;


 ...


    /**

     * @return array validation rules for model attributes.

     */

    public function rules() {

        // NOTE: you should only define rules for those attributes that

        // will receive user inputs.

        return array(

...

            // The following rule is used by search().

            // @todo Please remove those attributes that should not be searched.

            array('calcCharges, calcPayments, calcBalance, customer, supplier, partnerName, partnerFk, formType, headerNo, formDate, partnerFk, dueDate, referenceNo, truckNo, driver, memo, postingStatus', 'safe', 'on' => 'search'),

        );

    }


   ...


    /**

     * Add remember-filter-gridview behaviour

     * @return Array of behaviors

     */

    public function behaviors() {

        return CMap::mergeArray(parent::behaviors(), array(

                    'ERememberFiltersBehavior' => array(

                        'class' => 'application.components.ERememberFiltersBehavior',

                        'defaults' => array(), /* optional line */

                        'defaultStickOnClear' => false /* optional line */

                    ),

        ));

    }


...


    /**

     * Retrieves a list of models based on the current search/filter conditions.

     */

    public function search($accountType, $pageSize = 'FormHeader_pageSize', $page = 'FormHeader_page') {

        $calcChargesSql = "(SELECT SUM(d.unitPrice * d.quantity) FROM form_detail d WHERE d.headerFk = t.id)";

        $calcPaymentsSql = "(SELECT SUM(p.amount) FROM payment_detail p WHERE p.headerFk = t.id)";

        $calcBalanceSql = "(SELECT (c.totChr - p.totPay) FROM "

                . "(SELECT d.headerFk, SUM(d.unitPrice * d.quantity) AS totChr FROM form_detail d GROUP BY d.headerFk) c LEFT JOIN "

                . "(SELECT pd.headerFk, SUM(pd.amount) AS totPay FROM payment_detail pd GROUP BY pd.headerFk) p ON p.headerFk = c.headerFk WHERE c.headerFk = t.id)";


        $criteria = new CDbCriteria;

        $criteria->with = array('partner');


        // select

        $criteria->select = array(

            '*',

            $calcChargesSql . " AS calcCharges",

            $calcPaymentsSql . " AS calcPayments",

            $calcBalanceSql . " AS calcBalance",

        );


        $criteria->compare($calcChargesSql, MyActiveRecord::changeFormat($this->calcCharges));

        $criteria->compare($calcPaymentsSql, MyActiveRecord::changeFormat($this->calcPayments));

        $criteria->compare($calcBalanceSql, MyActiveRecord::changeFormat($this->calcBalance));




...


        $sort = new CSort;

        $sort->defaultOrder = 'dueDate ASC';

        $sort->attributes = array(

            'id' => array(

                'asc' => 'id ASC',

                'desc' => 'id DESC',

            ),

...

            'calcCharges' => array(

                'asc' => 'calcCharges ASC',

                'desc' => 'calcCharges DESC',

            ),

            'calcPayments' => array(

                'asc' => 'calcPayments ASC',

                'desc' => 'calcPayments DESC',

            ),

            'calcBalance' => array(

                'asc' => 'calcBalance ASC',

                'desc' => 'calcBalance DESC',

            ),

        );


        $sort->applyOrder($criteria);


        return new CActiveDataProvider($this, array(

            'criteria' => $criteria,

            'sort' => $sort,

            'pagination' => array(

                'pageSize' => Yii::app()->user->getState($pageSize, Yii::app()->params['defaultPageSize']),

                'currentPage' => Yii::app()->user->getState($page, 0),

            ),

        ));

    }


}



I tried with


$model->unsetAttribute($model->getSafeAttributeNames());

and also




$model->unsetAttributes(array('headerNo', 'partnerFk', 'formDate', 'dueDate', 'calcCharges', 'calcPayments', 'calcBalance'));



But still the calcCharges, calcPayments and calcBalance cannot be set to null with both.

Any idea other than directly set them to null?