Active Record does not update

Hi everyone…I’m new to Yii…

I’m writing a purchasing program for our company…it was written previously with PRADO…

i have decided to port it to Yii after reading a lot of comments about Yii being faster than prado and more…

However, I’ve come across this problem that I have never encountered with PRADO…

it’s about CActiveRecord not updating the data in the database even using a very simple code

such as:

    $coa = MST_COA::model()->find('account_id=3');


    $coa->description = 'ACCOUNT 5000';


    $coa->save();

However, inserting seems fine using the ff simple code:

  $coa = new MST_COA();


    $coa->description = 'ACCOUNT 5000';


    $coa->save();

with the primary key being auto generated.

The code snippet above seems to work fine with PRADO…

Am I missing something here?

Please help…thanks so much…

Maybe:


$coa = MST_COA::model()->find ( array ( 'account_id' => '3' ) );

$coa->description = 'ACCOUNT 5000';

$coa->save();

hmmm…i’ve added a




Yii::log(get_class($this).'/coa: account_id='.$coa->account_id );



and correctly outputs the account_id=3, concluding that the find has correctly returned an entry from the database.

updating it doesn’t seem to work though.

…oddly enough, there seems to be no error or exception being thrown if there really is something wrong…

Try




$coa = MST_COA::model()->findByPk(3);

$coa->description = 'ACCOUNT 5000';

$coa->save();



or if account_id is not your primary key




$coa = MST_COA::model()->findByAccount_id(3);

$coa->description = 'ACCOUNT 5000';

$coa->save();



hi…i just tried it a litter earlier…still no update…

but the ff:




$coa = MST_COA::model()->findByAccount_id(3);



threw an exception:




MST_COA does not have a method named "findByAccount_id".



MST_COA:




class MST_COA extends BaseDataModel{


	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}


	public function tableName()

	{

		return 'mst_coa';

	}


    

    public function getPrimaryKey(){

        return 'account_id';

    }


    public function relations(){

        return array(

            'MST_COA_TYPE' => array(self::BELONGS_TO, 'MST_COA_TYPE', 'account_type'),

                    );

    }


}



while from the database:




CREATE TABLE `mst_coa` (

  `account_id` int(10) unsigned NOT NULL auto_increment,

  `company_id` int(10) unsigned NOT NULL,

  `description` varchar(45) default NULL,

  `sub_account` tinyint(1) default NULL,

  `parent_account_id` int(10) unsigned default NULL,

  `normal_balance` int(10) unsigned default NULL,

  `account_class` int(10) unsigned default NULL,

  `account_type` int(10) unsigned NOT NULL,

  `position` varchar(45) default NULL,

  `created_by` int(10) unsigned default NULL,

  `created_date` datetime default NULL,

  `modified_by` int(10) unsigned default NULL,

  `modified_date` datetime default NULL,

  PRIMARY KEY  (`account_id`),

  UNIQUE KEY `description` (`description`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;



i have removed all constraints while checking the simple code above to work…

I have created a very simple site just to test CActiveRecord.

My Site Controller:





class SiteController extends CController{


    public function actionIndex(){


        $coa = MST_COA::model()->findByPk(1);

        $coa->description = 'This is your first account.';

        $coa->save();


	echo 'Your account is: '.$coa->description;

    }




}


class MST_COA extends CActiveRecord{


	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}


	public function tableName()

	{

		return 'mst_coa_2';

	}


    

    public function getPrimaryKey(){

        return 'account_id';

    }


    


}




For the database:




CREATE TABLE `mst_coa_2` (

  `account_id` int(10) NOT NULL auto_increment,

  `description` varchar(64) NOT NULL,

  PRIMARY KEY  (`account_id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;



Still no update…I don’t understand what’s happening here…It should be working normally just as it is working normally with PRADO…

I must be missing something big here…

INSERT operations work fine…but UPDATE…no good…I’ve just realized this problem right after testing my localsite with Editing records…

Check if

$coa = MST_COA::model()->findByPk(1);

returns an active record or null

yes…i’ve checked it…it returns:





object(MST_COA)#21 (10) {

  ["_md:private"]=>

  object(CActiveRecordMetaData)#10 (6) {

    ["tableSchema"]=>

    object(CMysqlTableSchema)#14 (9) {

      ["schemaName"]=>

      NULL

      ["name"]=>

      string(9) "mst_coa_2"

      ["rawName"]=>

      string(11) "`mst_coa_2`"

      ["primaryKey"]=>

      string(10) "account_id"

      ["sequenceName"]=>

      string(0) ""

      ["foreignKeys"]=>

      array(0) {

      } 

      ...

  ["_new:private"]=>

  bool(false)

  ["_attributes:private"]=>

  array(2) {

    ["account_id"]=>

    string(1) "1"

    ["description"]=>

    string(16) "My First Account"

  }

  ["_related:private"]=>

  array(0) {

  }

  ["_c:private"]=>

  NULL

  ["_errors:private"]=>

  array(0) {

  }

  ["_va:private"]=>

  NULL

  ["_se:private"]=>

  string(0) ""

  ["_e:private"]=>

  NULL

  ["_m:private"]=>

  NULL




i’m really quite puzzled…it was supposed to be working…hmmmm…

What if you use save(false) to skip validation?

Do you use 1.0 or 1.1a? I don’t know but 1.1 may need a validation rule (perhaps only for massive assignment of attributes).

/Tommy

i have delved into CActiveRecord, CDbCommandBuilder and CDbCommand and added some logging within some methods and

i was able to come up with these logs:

2009/10/16 19:06:10 [info] [application] CDbCommandBuilder/createPkCriteria table->primaryKey =account_id

2009/10/16 19:06:10 [info] [application] CDbCommandBuilder/createPkCriteria pk=Array

2009/10/16 19:06:10 [info] [application] CDbCommandBuilder/createPkCriteria array content pk=11

2009/10/16 19:06:10 [info] [application] CDbCommandBuilder/createPkCriteria condition after $this->createInCondition =mst_coa.account_id=11

2009/10/16 19:06:10 [info] [application] MST_COA/update to execute. Check pk account_id=11

2009/10/16 19:06:10 [info] [application] CDbCommandBuilder/createPkCriteria table->primaryKey =account_id

2009/10/16 19:06:10 [info] [application] CDbCommandBuilder/createPkCriteria pk=Array

2009/10/16 19:06:10 [info] [application] CDbCommandBuilder/createPkCriteria array content pk=account_id

2009/10/16 19:06:10 [info] [application] CDbCommandBuilder/createPkCriteria condition after $this->createInCondition =mst_coa.account_id=0

2009/10/16 19:06:10 [info] [application] CDbCommandBuilder/createUpdateCommand to execute

2009/10/16 19:06:10 [info] [application] CDbCommandBuilder/createUpdateCommand criteria condition:mst_coa.account_id=0

2009/10/16 19:06:10 [info] [application] CDbCommandBuilder/createUpdateCommand sql:UPDATE mst_coa SET account_id=:yp0, company_id=:yp1, description=:yp2, sub_account=:yp3, parent_account_id=:yp4, normal_balance=:yp5, account_class=:yp6, account_type=:yp7, position=:yp8, sub_level=:yp9, created_by=:yp10, created_date=:yp11, modified_by=:yp12, modified_date=:yp13 WHERE mst_coa.account_id=0

hmmm…

mst_coa.account_id=0

is this normal??? seems not… something must have been wrong…

hi tommy…yeah, i’ve tried it already…i removed all validations, rules…i even stripped down everything down to the simplest code

i could think of…and still no update…my PRADO app is running on the same machine with my Yii app…and with PRADO…all update transactions are ok…

from Yii’s change log…

it says:

Version 1.0.9 September 6, 2009

adding more logs within cactiverecord,cdbcommand and cdbcommandbuilder:





class SiteController extends CController{


    public function actionIndex(){

	

	Yii::log(get_class($this).'/actionIndex to retrieve data from DB');

        $coa = MST_COA::model()->findByPk(11);

        //echo '<pre>';

        //var_dump($coa);

        //echo '</pre>';

	Yii::log(get_class($this).'/actionIndex to modify data and save to DB');

        $coa->description = 'Paid-in Capital:xx xx';

        $coa->save();

	

	echo 'Your account is: '.$coa->description;

    }




}




results to:

2009/10/16 19:53:28 [info] [application] SiteController/actionIndex to retrieve data from DB

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createPkCriteria table->primaryKey =account_id

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createPkCriteria pk=Array

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createPkCriteria array content pk=11

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createInCondition $columnName is simple key.

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createInCondition $columnName=account_id

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createInCondition check foreach $values

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createInCondition value=11

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createInCondition $n===1 (count of values)

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createInCondition mst_coa.account_id=11

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createPkCriteria condition after $this->createInCondition =mst_coa.account_id=11

2009/10/16 19:53:28 [info] [application] SiteController/actionIndex to modify data and save to DB

2009/10/16 19:53:28 [info] [application] MST_COA/update to execute. Check pk account_id=11

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createPkCriteria table->primaryKey =account_id

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createPkCriteria pk=Array

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createPkCriteria array content pk=account_id

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createInCondition $columnName is simple key.

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createInCondition $columnName=account_id

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createInCondition check foreach $values

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createInCondition value=account_id

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createInCondition $n===1 (count of values)

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createInCondition mst_coa.account_id=0

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createPkCriteria condition after $this->createInCondition =mst_coa.account_id=0

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createUpdateCommand to execute

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createUpdateCommand criteria condition:mst_coa.account_id=0

2009/10/16 19:53:28 [info] [application] CDbCommandBuilder/createUpdateCommand sql:UPDATE mst_coa SET account_id=:yp0, company_id=:yp1, description=:yp2, sub_account=:yp3, parent_account_id=:yp4, normal_balance=:yp5, account_class=:yp6, account_type=:yp7, position=:yp8, sub_level=:yp9, created_by=:yp10, created_date=:yp11, modified_by=:yp12, modified_date=:yp13 WHERE mst_coa.account_id=0

i noticed during the find operation: the criteria->condition is equal to mst_coa.account_id=11

allowing the data to be retrieved…

during the save/update operation, the criteria->condition becomes mst_coa.account_id=0

this might be the reason why there is no update on the database.

geezzz… i seemed to have found the solution…after investigating line by line some methods of CActiveRecord, CDbCommandManager and CDbCommand,

i realized primaryKey() should be overridden, not the getPrimaryKey() method of CActiveRecord… :D

:D silly me