Skip to content
This repository

Using virtual attributes in a model -> a discrepancy IMHO #1899

Open
Ziggizag opened this Issue · 2 comments

3 participants

Ziggizag Raman Sinha Carsten Brandt
Ziggizag

I have a problem to call it a bug... this is more like a design flaw.
Let me explain:

Presume we have a model with two attributes:

'forename' and 'surname'

Then, we want to show the active record data using a calculated column (a virtual attribute) called 'fullname'.

So we declare a new attribute within a model:

public $fullname;

function getFullname()
{
return $this->surname . ', ' . $this->forename;
}

We would expect this is enough to use this new virtual attribute for search criteria but we fail. We see all search is accomplished via pretty direct databes queries, so we need to wriite more code:

public function search()
{
$criteria=new CDbCriteria;
$criteria->select = array('*', 'CONCAT(surname, ", ", forename) AS fullname');
$criteria->compare('CONCAT(surname, ", ", forename)', $this->fullname, true);

return new CActiveDataProvider($this, array(
    'criteria'=>$criteria,
    'pagination'=>array('pageSize'=>10),
     'sort' => array(
                  'attributes'=>array('CONCAT(surname, ", ", forename) AS fullname',),
                  'defaultOrder' => 'fulname ASC',
             ),
));

}

Well - we are near happy solution but... we can immediately notice that "Fullname" column displayed in CGridView is not sortable. The question is... WHY ???

And the nasty answer is, because CSort class resoves attributes using:

CActiveRecord::model($this->modelClass)->hasAttribute($attribute)

And 'hasAttribute' method of CActiveRecord is entirely based on CActiveRecordMetaData, so it is completely unaware of our virtual attributes behind a computed column!

This is a desgin flaw in my humble opinion. I am afraid it is the origin of multiple problems with usage of computed columns in the scope of active records what cannot be easily resolved because virtual attributes are not being recognized by 'hasAttribute' method.

Please - think about and comment if feasible! And even better - correct it if necessary!

Raman Sinha
Ziggizag

A fellow Yii forum member seenivasan instructed me of this working solution:

$sort->attributes = array('*', "fullname"=>array(
"asc"=>"CONCAT(surname, ", ", forename) ASC",
"desc"=>"CONCAT(surname, ", ", forename) DESC",
));

Anyway - IMHO - all these is just a workaround. It would be much more simple if virtual attributes were recognized by 'hasAttribute' method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.