Model Nie Chce Aktualizować Rekordu Mimo Braku Błędów

Mam taką funkcję w modelu formularza od zarządzania profilem:




public function update($id)

        {

            $u = Users::model()->findByPk($id);

            $u->firstname = $this->firstname;

            $u->lastname = $this->lastname;

            $u->address = $this->address;

            $u->postcode = $this->postcode;

            $u->city = $this->city;

            $u->phone = $this->phone;

            

            if(!empty($this->email))

                $u->email = $this->email;

            

            if(!empty($this->password))

            {

                $salt = $this->generateSalt();

                $u->password = $u->encodePassword($this->email, $this->password, $salt);

                $u->salt = $salt;

            }

            $u->save();

            

            

        }



Mimo to, że wszystkie dane są wysyłane poprawne (sprawdzałem CVarDebugger’em, zarówno $this jak i $u po wprowadzeniu danych), a save() w modelu i validate() w kontrolerze nie wyrzucają żadnych błędów to rekord nie chce się zaaktualizować.

Gdzie jest błąd?

Funkcja w kontrolerze wygląda w taki sposób:




public function actionEdit()

    {

         if(Yii::app()->user->isGuest)

                throw new CHttpException('403');

         

         

         $model = new FormProfile('edit');       

         if (isset($_POST['FormProfile'])) {

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

                if ( $model->validate() ) {

                        $model->update(Yii::app()->user->id);

                }

        }

        else

        {

            $model->attributes = Users::model()->findByPk(Yii::app()->user->id)->attributes;

            $model->password = NULL;

        }

        

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

            'model' => $model,

        ));

    }



Co zwraca save() ? Spróbuj włączyć profilowanie zapytań sql i zobacz co się wysyła do serwera baz danych. Możesz jeszcze pokazać model Users ?

Cześć

Spróbuj używać metody save() z parametrem false czyli




$u->save(false);



metoda save przed wykonaniem update lub create domyślnie włącza walidację modelu (i tu też miałem klopoty z walidacją mimo, że wszystki reguły były ok :) ) jeżeli ustawisz pierwszy parametr na flase nie zadziała wtedy walidacja i wykona się update lub create. Jeżeli nadal będą problemy spróbuj użyć metody saveAttributes() http://www.yiiframework.com/doc/api/1.1/CActiveRecord#saveAttributes-detail

Niestety to nie działa. Próbowałem dać wszystkie parametry do tablicy i potem wywołać przez saveAttributes, dla save() dać false. Nic nie działa. Profilowanie zapytań sql nic nie wyświetla. save() zwraca zawsze true.

Model Users:




<?php


class Users extends CActiveRecord {

    


	public static function model($className = __CLASS__) {

		return parent::model($className);

	}


	public function tableName() {

		return '{{users}}';

	}


	public function getPrimaryKey() {

		return 'ID';

	}


	public function relations() {

		return array(

                         'serversCount' => array(

                                  self::STAT,

                                  'Servers',

                                  'uid',

                         ),

		);

	}




	public function encodePassword($mail, $password, $salt) {

		$password = hash('sha256', $mail.$salt.$password);

		return $password;

	}


}


?>



Przed


$u->save();

zobacz czy wszystkie atrybuty są ustawione prawidłowo


$u->attributes

Proponuje jednak dodać metodę rules() do modelu Users, i np. dla wszystkich atrybutów ustawić ‘safe’, to powinno rozwiązać problem.

A tutaj trochę więcej informacji:

save() zwraca true, bo zostały zapisane bezbłędnie wszystkie atrybuty na które model pozwala. Skoro nie masz żadnych reguł to nic się nie zapisuje. Musi być jakaś reguła walidacji chociażby ‘safe’.

Inne sprawa to dlaczego masz dwa modele - Users oraz FormProfile. Zastanów się, czy na pewno jest taka potrzeba.

W $u->attributes wszystko jest ustawione poprawnie.

Users dziedziczy od CActiveRecord, FormProfile od CFormModel, a rules mam w FormProfile:




public function rules(){

		return array(

			 /* global rules */

			 array('email','email'),

			 array('email','EditValidator','attributeName'=>'email','className'=>'Users',),

			 array('username','length','min'=>5,'max'=>50),

			 array('username','EditValidator','attributeName'=>'username','className'=>'Users'),

			 array('password','length','min'=>6),

			 /* register rules */

			 array('username,email,password,passwordRepeat','required','on'=>'register'),

                         array('password','compare','compareAttribute'=>'passwordRepeat','on'=>'register'),

			 array('captcha','ext.recaptcha.EReCaptchaValidator','privateKey'=>Yii::app()->params->captcha['private'],'on'=>'register'),

                         

                         /* edit profile rules */

                         array('firstname,lastname,address','length','min'=>5,'max'=>150,'on'=>'edit'),

                         array('city','length','min'=>3,'max'=>150,'on'=>'edit'),

                         array('postcode','length','min'=>6,'max'=>6,'on'=>'edit'),

                         array('phone','length','min'=>7,'max'=>25,'on'=>'edit'),

                );

	}



Ale nie masz w modelu Users. save() wywołujesz na obiekcie klasy Users, a nie FormProfile. Musisz stworzyć rules w klasie Users i ustawić walidatory atrybutów typu "safe".

Dodałem do modelu Users:





        public $username;

	public $email;

	public $password;       

        public $firstname;

        public $lastname;

        public $address;

        public $postcode;

        public $city;

        public $phone;


        public function rules(){

		return array(

			 array('email,username,password,firstname,lastname,address,city,postcode,phone','safe'),

                );

	}



Jednak nadal nie chce przepuścić danych do DB…

// Edit

Problem rozwiązany. Był on związany z tym, że w modelach zamiast funkcji primaryKey() tworzyłem getPrimaryKey() <facepalm>