Beforesave И Update

Здравствуйте. Наверное простой вопрос, но я не смог его сформулировать для поисковика.

Есть модель User в которой следующее:




public function rules()

	{

		

		return array(

		        ...

			array('created','safe'),

			

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

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

			array('id, username, role', 'safe', 'on'=>'search'),

			

		);

	}

...

protected function beforeSave() 

	{

		if($this->isNewRecord)

		{

			$this->created = time();

			$this->role = 0;

		}

		

		if($this->new_password) 

			$this->password = $this->hashPassword(trim($this->new_password));

			

		return parent::beforeSave();

	}


Controller

...

public function actionPassword($id)

	{

		$model = $this->loadModel($id);

		

		if(isset($_POST['User']))

		{

			$model->attributes = $_POST['User'];

			if($model->save())

			{

				Yii::app()->user->setFlash('updatePass','User password was change');

				$this->redirect(array('password','id'=>$model->id));

			}

		}

		$this->render('password',array(

			'model'=>$model,

		));

	}

...



Проблема в том, что при создании нового юзера, в поле created заносится дата создания нормально, но

при апдейте записи о юзере (смена пароля), поле created тоже апдейтится, туда заносится 0.

Как этого избежать ?

Ну, во-первых, created имеет смысл выкинуть из списка safe - один фиг, руками присваивается значение.

А вообще, странно это. А точно при создании нормальное значение в БД попадает? А в форме апдейта нет поля created?

Ну поле в safe я добавил от безысходности, раньше его там не было, думал мож поможет.

В форме только пароль и пароль на подтверждение

Ваш код слишком перегружен. Зачем array(‘created’,‘safe’) ? что бы можно было менять время создания через форму? Логика подсказывает, что это поле не должно редактироваться пользователем вообще, значит это лишнее.

На вашем бы месте, я сделал в базе поле created типом TIMESTAMP и поставил бы ему "DEFAULT CURRENT_TIMESTAMP" и тогда в коде не нужно ни о чем заботится.

PS: о, тут и без меня ответили про лишний "safe"

PSS: почему не работает как ожидается и мне не понятно, попробуйте выводить в лог или в браузер $this->attribures и $this->isNewRecord в beforeSave() может это прояснит ситуацию

проверил $this->attribures перед сохранением, там данные которые выбрались при загрузке модели, в том числе и дата создания старая

В MYSQL есть возможность для поля задать атрибут автообновление при редактировании записи. (on update CURRENT_TIMESTAMP).

Проверьте, просто изменив запись в БД напрямую, не изменяется ли дата? Возможно следует отключить этот тригер.

Проверил, напрямую апдейтнулось без ошибок.

Кстати, при апдейте через скрипт, в базу на место старого времени заносится число 4

parent::beforeSave() не подгаживает ли?

ну, вдруг Вы от какой-нибудь своей базовой модели отнаследовались.

Да это магия какая-то, то 1 то 4 откуда числа такие? Какого типа вообще это поле? Можно SQL код создания таблицы увидеть? Никаких хранимых процедур ведь нет? Мало ли.

И каким SQL запросом вы вользовались, когда " на место старого времени заносится число 4"?

parent::beforeSave() - без понятия… как я понял, его надо обязательно прописывать




CREATE TABLE IF NOT EXISTS `tbl_user` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `username` varchar(128) COLLATE utf8_unicode_ci NOT NULL,

  `password` varchar(128) COLLATE utf8_unicode_ci NOT NULL,

  `salt` varchar(128) COLLATE utf8_unicode_ci NOT NULL,

  `created` int(11) NOT NULL,

  `role` int(11) NOT NULL,

  PRIMARY KEY (`id`)

) 




про число 1 я ошибся, сохраняется число 4.

Запроса нет, я делаю $model->save()

P.S.

class User extends CActiveRecord

тут я не наследовался ни от чего левого

  1. есть смутные воспоминания, что может быть вызывать parent::beforeSave() нужно перед своим кодом, а не после.

  2. может вместо protected beforeSave правильнее использовать public onBeforeSave

  3. попробуйте вообще закоментировать у себя beforeSave, непонятные данные в поле created все также будут писаться?

  4. попробуйте сменить тип created на TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP а то INT для хранения данных, это не красиво, лишние телодвижения потом нужны, что бы красиво отображать. (хотя по внутреннему строение TIMESTAMP и является INT)

1 - попытался, результат вообще не апдейтнулся

2 - реакция та же на паблик

3 - сделал, все равно бред сохранился, тоесть проблема видимо не тут

Странная проблема.

Проверьте, срабатывает ли




                if($this->isNewRecord)

                {

                        $this->created = time();

                        $this->role = 0;

                }



как при create. так и update. Не верится в это.

у меня это метод выглядит так:




	protected function beforeSave()

	{

		if(!parent::beforeSave())

			return false;


            

        if($this->isNewRecord) 

            $this->created_by_id=(Yii::app()->user->id) ? Yii::app()->user->id : 0;

                        

		return true;

	}



Используйте поведение




	public function behaviors()

	{

		return array(

			'zii.behaviors.CTimestampBehavior',

		);

	}



в БД создайте поля

create_time

update_time




                if($this->isNewRecord)

                {

                        $this->created = time();

                        $this->role = 0;

                }



Срабатывает правильно, а вот про поведение не совсем понял. Еще ни разу не приходилось юзать его. Что оно даст ?