Save() Does Not Work Due To (Unrelated?) Rule For Other Column

Hello everybody,

having a little issue here. I wanna update the field ‘lastactive’ field in my database after a successful login. This is my changed UserIdentity::authenticate() method:




private $_id;

 

public function authenticate()

{

	// $this->username === provided email in call

	$dbuser=User::model()->findByAttributes(array('email'=>$this->username));

	if($dbuser === null) // no user was found in the database

		$this->errorCode=self::ERROR_USERNAME_INVALID;

	if(!CPasswordHelper::verifyPassword($this->password, $dbuser->password)) // wrong password

		$this->errorCode=self::ERROR_PASSWORD_INVALID;

	else { // OK!

		$this->setLoginAttributes($dbuser);

		$this->errorCode=self::ERROR_NONE;

	}

	return !$this->errorCode;

}


public function setLoginAttributes($dbuser)

{

	$this->_id = $dbuser->id;

	$this->setState('first_name', $dbuser->first_name);

	$this->setState('last_name', $dbuser->last_name);

	$this->setState('status', $dbuser->status);

	$dbuser->lastactive = New CDbExpression('NOW()');

	$dbuser->save(array('lastactive'));

}


public function getId()

{

	return $this->_id;

}



But the save operation doesn’t work. So I checked if it does with SaveAttributes(array(‘lastactive’)), and it does. So I assumed it’s a problem with my validation rules. I checked them one after another, and turned out the one who causes the problem is the fourth from the top about my birthday column:




public function rules()

{

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

	// will receive user inputs.

	return array(

		array('email, password', 'required'),

		array('email', 'email'),

		array('email', 'unique'),

		array('birthday', 'date'),

		array('active, online, address_id', 'numerical', 'integerOnly'=>true),

		array('first_name, last_name, email, image', 'length', 'max'=>255),

		array('about', 'length', 'max'=>4000),

		array('status', 'length', 'max'=><img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' />,

		//array('password', 'length', 'is'=>60),

		array('birthday, joined, lastactive', 'safe'),

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

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

		array('id, first_name, last_name, email, birthday, about, joined, lastactive, status, active, image, online, password, address_id', 'safe', 'on'=>'search'),

	);

}



Can somebody explain me why the reason for that?

Thanks in advance!

So, I’ve found out what my problem is: The column defaults to yyyy-MM-dd (MySQL default), while the CDateValidator defaults to dd-MM-yyyy (I think). So I changed my rule to




array('birthday', 'date', 'format' => 'yyyy-MM-dd'),



and now it works fine. I think the problem was that during registration I didn’t give my user a birthday, and thus MySQL defaulted to 0000-00-00. So, on update, Yii noticed that my entry was in the wrong format. Still I’m kinda confused: Does Yii check every attribute before saving, although I told it to only save the ‘lastactive’ entry?

Cheers!

I’m going to go with ‘’ is no a valid date :)

I think what is going on is that $model->save() goes through validation. $model->updateByAtributes() doesn’t.

For what you are doing the byAttribute route is better. The SQL generated is cleaner. Not much of a problem on a small site, but if it grows…

Thanks a lot for your answer! I already found out that it’s rules related, see my previous post. Still confused about it, but I only started out with Yii a couple of weeks ago ;) Could you maybe elaborate on the UpdateByAttributes() suggestion? Can’t find it in the CActiveRecord class reference, but there seems to be update(), updateAll() and updateByPk().

Thanks again!

I was explaining ‘why’ you might be getting the error. updateByAttribute was OTMH, What I meant was saveAtribute(),




        $dbuser->lastactive = New CDbExpression('NOW()');

        $dbuser->saveAttributes(array('lastactive'));



From the Docs

Thanks, I went with update(‘lastactive’) now and it works just fine (used SaveAttributes before and did the job as well, see my OP).