Yii Framework Forum: CActiveRecord::save() issue - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

CActiveRecord::save() issue Rate Topic: -----

#1 User is offline   journey4712 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 8
  • Joined: 02-July 09

Posted 24 February 2010 - 01:29 AM

So i was programming away and ran into an issue where an object is created, saved, updated and saved again. I had the problem in full class, but whittled it down to the following test case. this test code assumes Yii::app()->db points to an sqlite database.

For now I'm using the following workaround before saving since i don't use the ability to change the primary key value.
$model->setPrimaryKey($model->id);


Seems perhaps some logic is needed when setting the oldPrimaryKey on insert

Yii::app()->db->createCommand('CREATE TEMP TABLE IF NOT EXISTS activeRecordTest ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,title TEXT )')->execute();
class someModel extends CActiveRecord {
  public function tableName() { return 'activeRecordTest'; }
}

class activeRecordTest extends CTestCase
{

  public function testSaveTwice()
  {
    $record = new someModel;
    $record->title = 'The Title';
    $this->assertTrue($record->save(), 'initial save');

    $record->title = 'The Name';
    $this->assertTrue($record->save(), 'second save');
    $this->assertEquals('The Name', $record->title, 'before refresh');
    $this->assertTrue($record->refresh(), 'refresh');
    $this->assertEquals('The Name', $record->title, 'after refresh');
  }
}


phpunit reports
There was 1 failure:

1) activeRecordTest::testSaveTwice
after refresh
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-The Name
+The Title

/var/www/nmtdvr/protected/tests/unit/activeRecordTest.php:21

FAILURES!
Tests: 1, Assertions: 5, Failures: 1.


the relevant logging is
2010/02/23 22:19:23 [trace] [system.web.CModule] Loading "log" application component
2010/02/23 22:19:23 [trace] [system.web.CModule] Loading "db" application component
2010/02/23 22:19:23 [trace] [system.db.CDbConnection] Opening DB connection
2010/02/23 22:19:23 [trace] [system.db.CDbCommand] Executing SQL: CREATE TEMP TABLE IF NOT EXISTS activeRecordTest ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,title TEXT,name TEXT )
2010/02/23 22:19:23 [trace] [system.db.CDbCommand] Querying SQL: PRAGMA table_info('activeRecordTest')
2010/02/23 22:19:23 [trace] [system.db.CDbCommand] Querying SQL: PRAGMA foreign_key_list('activeRecordTest')
2010/02/23 22:19:23 [trace] [system.db.ar.CActiveRecord] someModel.insert()
2010/02/23 22:19:23 [trace] [system.db.CDbCommand] Executing SQL: INSERT INTO 'activeRecordTest' ("title") VALUES (:yp0). Bind with parameter :yp0='The Title'
2010/02/23 22:19:23 [trace] [system.db.ar.CActiveRecord] someModel.update()
2010/02/23 22:19:23 [trace] [system.db.ar.CActiveRecord] someModel.updateByPk()
2010/02/23 22:19:23 [trace] [system.db.CDbCommand] Executing SQL: UPDATE 'activeRecordTest' SET "title"=:yp0, "id"=:yp1 WHERE 'activeRecordTest'."id" IS NULL. Bind with parameter :yp0='The Name', :yp1=1
2010/02/23 22:19:23 [trace] [system.db.ar.CActiveRecord] someModel.refresh()
2010/02/23 22:19:23 [trace] [system.db.ar.CActiveRecord] someModel.findByPk()
2010/02/23 22:19:23 [trace] [system.db.CDbCommand] Querying SQL: SELECT * FROM 'activeRecordTest' 't' WHERE 't'."id"=1 LIMIT 1


journey4712
0

#2 User is offline   journey4712 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 8
  • Joined: 02-July 09

Posted 27 February 2010 - 01:19 PM

Just a bump here, is this me mis-using CActiveRecord, a bug in CActiveRecord, or ? Curious to hear opinions. As for a workarround i've found using $model->setPrimaryKey($model->id) will fix up CActiveRecord->$_pk being null.

journey4712
0

#3 User is offline   Maurizio Domba Cerin 

  • Yii - Yesss It Is !!!
  • Yii
  • Group: Yii Dev Team
  • Posts: 4,342
  • Joined: 12-October 09
  • Location:Croatia

Posted 01 March 2010 - 08:16 AM

Problem is that update() uses getOldPrimaryKey() and in this case the oldPrimaryKey ($this->_pk in CActiveRecord.php) is not set...

Maybe the refresh() method should update the oldPrimaryKey.

As it says the refresh() repopulates the active record with the latest data, so the next update should use the new values so it should use the new primary key... and for update() to use it the only way is to set the getOldPrimaryKey()...
Find more about me.... btw. Do you know your WAN IP?
0

#4 User is offline   intel352 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 196
  • Joined: 05-February 10
  • Location:Southport, NC

Posted 01 March 2010 - 12:23 PM

I'm curious, why would you be updating the same record multiple times in the same request?
While you have seemed to verify that this is a bug in the operation of ActiveRecord (as it's not updating the old pk value), it also seems that your own code isn't very optimal, if it's creating *and* updating a single record in the same request.

To avoid this issue, I would refactor your code so that you only create or update once per request, unless your situation truly justifies your approach.

Additionally, if you don't mind, would you report this issue as a bug?
http://code.google.c...ii/issues/entry
Need live Yii support? - Join the #yii IRC channel on Freenode!
0

#5 User is offline   abajja 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 108
  • Joined: 05-March 09
  • Location:Barcelona, Spain

Posted 01 March 2010 - 12:42 PM

The static method model() is required for every AR class.
So
class someModel extends CActiveRecord {
  public function tableName() { return 'activeRecordTest'; }
}

should be like
class someModel extends CActiveRecord {

  public static function model($className=__CLASS__) {
        return parent::model($className);
  }
  public function tableName() { return 'activeRecordTest'; }
}

0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users