determine which attributes are changed of an ActiveRecord

Hi All

Is it possible to check if an attribute is changed or not, for example:




if ( $user->isChanged('address') ) { .... }



If you would use lazy loading a test like




if ( isset($user->Company) ) { ... }



would still require loading the Company, and its still unknown if the Company is changed (an object with a different primary key) or not!

If something like this is not implemented, any suggestions how it can be solved ?

cheers

Maybe the new Query caching can fit you.

You can cache the query for retrive the company, if the company changes Yii will repeat the query.

save old attributes of AR in a variable in AR::afterFind()




public function afterFind()

{

    $this->_oldAttrbiutes = $this->attributes;

}



compare and handle in AR::beforeSave()

Thanks for the answers. But I still have a problem. Suppose I have a relation as follows:

User.php:


'address'	=> array(self::BELONGS_TO, 'Company', 'company_id'),



So when I do:




$u = User::model()->findByPk(10) ;

..... do some undetermined stuff here .....


if ( isset($u->company) ) {  // load the Company object!!

    $u->company_id = $u->company->id ;

}



How do I tell if the Company object was set/changed. For example, if nothing happend during the … undetermined stuff… to the company, the above if-statement will have the result that the company is loaded from the database. Any suggestions ?

not sure what you’re asking. please rephrase

I think that maybe you could make good use of one of the audit extensions:

http://www.yiiframework.com/search/?q=audit&type=extension〈=

It basically allows you to track changes to your models.

Perfect for the job, I’d think. :)

I actually wanted to implement something like this into an extension/behavior ?

UPDATE: I guess the only solution is maybe to override the magic method: __get/__set ? Can this be done with an extension/behavior?

UPDATE: overriding __get/__set in a behavior doesn’t seem to work :(

The problem can be defined as follows: given an object $user (which BELONGS_TO a Company)

The only thing you know about this $user is that some attributes have changed.

Now, if the company has changed, you have to add its primaryKey value to company_id like:




if ( isset($user->company) ) {

   $user->company_id = $user->company->id

}

$user->save() ;



Easy, but if the company didn’t change, you have just done some useless DB queries, which might not be good for performance!

This is also a problem with other relations! There seems to be no way to tell which attributes have changed!

Cheers

public function isChanged($atributo)
{
return (isset($this->getDirtyAttributes()[$atributo]));
}