Model save bug


This is long story - I will give you some background, so you will see why it is like that:

I am building some highly specialized task/workload management application for ~300 employees company.

As this is already some remarkable organization, there is a lot of human traffic behind and this is managed by HR department and is reflected in active directory and finally in LDAP. This traffic are people being employed and people who were lied-off or resigned as well as names changes due to marriage or other reasons.

Thus I decided Yii user database (MySQL) for my application to use LDAP’s ‘login’ field as primary key. I have used adLDAP class to connect to LDAP and all personal data (name, surname, email-address, location) is presented ‘online’ based on LDAP-based information while all application-specific information (user role, user permissions, etc.) is stored in Yii database.

That required me to include many LDAP-driven virtual atributes in my "users" model like this one for instance:

public $LDAP2Yii;


public function __construct($arg = NULL) {


   $this->LDAP2Yii = new LDAP2Yii(); //where LDAP2Yii is my helper extension class providing adLDAP functionality


public function getUserName(){

   $LDAP2Yii = $this->LDAP2Yii;

   $user = $LDAP2Yii->getUser($this->login);

   return $user['name'];


Well, using virtual attributes this way allowed me to have all model functionality performing well excluding "create" feature. I can browse records, I can update records but I fail to add new users in a regular manner. For whatever reason saving a new model fails with no error (no new record created but no trace off any error in logs) while using model->insert() fails with famous:

CDbException Description The active record cannot be inserted to database because it is not new.

(BTW - this message is pure meaningless nonsense in fact).

The only workaround is using direct database access bypassing active record. This way I can save new user (login + application specific data) to Yii database but I believe this is bug not feature.


By the error code it means that the user model is not a new created record but a retrieved one so save() does an update instead of insert…

Can you post your code for adding the user?


This are model’s rules:

public function rules()


   return array(

      array('nick', 'required', 'message'=>'{attribute} must not be empty !'),

      array('nick', 'length', 'encoding'=>'utf8', 'min'=>2, 'max'=>3, 'tooShort'=>'Nick must be 2 or 3 letters long !', 'tooLong'=>'Nick must be 2 or 3 letters long !'),

      array('role', 'in', 'allowEmpty'=>FALSE, 'range'=>array('admin','user'), 'message'=>"Role must be either 'admin' or 'user' !"),

      array('dispatcher', 'boolean', 'allowEmpty'=>FALSE, 'strict'=>TRUE, 'message'=>"Dispatcher value must be boolean !"),

      array('active', 'boolean', 'allowEmpty'=>FALSE, 'strict'=>TRUE, 'message'=>"Active value must be boolean !"),



And this is controler code:

public function actionCreate()


   $model = new User;

   //default values

   $model->nick = '';

   $model->role = 'user';

   $model->dispatcher = 0;

   $model->active = 1;



      $model->login = trim($_POST['User']['login']);

      $model->nick = mb_strtoupper(trim($_POST['User']['nick']));

      $model->role = trim($_POST['User']['role']);

      $model->dispatcher = trim($_POST['User']['dispatcher']);

      $model->active = trim($_POST['User']['active']);



      $this->render('create', array('model'=>$model));




This code seems OK… are you sure that the error is regarding this model? check the error call stack to see on which line it fires… does it fire on that $model->save() or maybe some other… and I don’t see from the above code how is this connected to the code in your first post?


It seems the crucial point is this one:

public function __construct($arg = NULL) {


   $this->LDAP2Yii = new LDAP2Yii();


It seems extending default constructor this way breaks its functionality in case of saving model.

Yeap !!!

The solution is:

Forget extending CActiveRecord constructor!!!

Initialise all "extra" variables this way:

private $LDAP2Yii;


public function init() {

   $this->LDAP2Yii = new LDAP2Yii();


Public ‘init’ function is called by class constructor right after all metadata get initialized, so this is the right place to initialize variables what are needed elsewhere in the model code afterwards.

Case is closed!!!

Great you solved it…

I just now checked the CActiveRecord construct to see why it would not work extending it and found the problem.

In the constructor by default the value of the argument is “insert” while you set it to be NULL :D


   public function __construct($scenario='insert')

your code


   public function __construct($arg = NULL)


Yeap - good shot!

I need to get habitual checking in GIT how given class is scripted - this can save hours of nasty trials and errors!

Thank you fo assistance - Yii is GREAT fun for me - I love it!!!