Tricky AR: unset() and unsetAttributes()

Some tricky behavior of AR attributes unsetting.

Simple AR model editing:


$model=Post::model()->findByPk(1);

$model->title='Simple title';

$model->text='';

$model->save();

If you need to Do Not Save field ‘text’ to database (if it’s was empty for example)

and leave value from database, you need to use:


unset($model->text);

If you use:


$model->text=null;

or identical CModel function


$model->unsetAttributes(array('text'));

Then field will be saved with an empty value.

Maybe it’s not mistake, but guess unsetAttributes() and unset() should work the same manner.

FYI save() has an optional second parameter with an array of fields to save. If you just want to save the title to the database just do




$model->save(true, array('title'));



true means “use validation before saving”, if you set it to false you can bypass validation (comes in handy if you’ve executed validation yourself before the save() call and don’t need to run it again).

Agree. I know this feature. But it’s not handy to use it if you have lots of attributes where you need to avoid saving only few of them.

unset() is a PHP function that destroys a variable - http://php.net/manual/en/function.unset.php

unsetAttributes() is a Yii function that sets all model attributes to null - http://www.yiiframework.com/doc/api/1.1/CModel#unsetAttributes-detail

unsetAttributes() is used to "clear" the default values (if needed) that the model gets from the database.

I clearly understand this. This topic is not about functions itself. Its about the ways they work and named.

In this case unsetAttributes() better should looks like nullifyAttributes(). This is just a little remark.

PS: Is there any Yii method (except as said ScallioXTX) to tell AR model not to save custom attributes?

Sorry, but I’m fairly certain this is not entirely true. The thing is that CActiveRecord inherits from CComponent, which in turn has a magic __unset which sets the property to be unset to null (see http://www.yiiframework.com/doc/api/1.1/CComponent#__unset-detail).

Since a field in an active record is not an actual field (i.e. it’s not explicitly defined in the class) the magic method will be called.

I can’t fathom why this would be different that unsetAttributes() though, as it clearly is …