determine which attributes are changed of an ActiveRecord

(Jeanluca) #1

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 ?


(Matteo Falsitta) #2

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.

(mbi) #3

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

public function afterFind()


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


compare and handle in AR::beforeSave()

(Jeanluca) #4

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


'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 ?

(el chief) #5

not sure what you’re asking. please rephrase

(Jacob Moen) #6

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

It basically allows you to track changes to your models.

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

(Jeanluca) #7

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 :(

(Jeanluca) #8

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!


(Pedro) #9

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