moggizx
moggizx

Reputation: 476

$model->save() returns true but no record is created, id is null

I have this code in my controller's actionCreate that is called via Ajax:

if ($model->save() === true)
{
    echo CJSON::encode(array('id' => $model->id);
    Yii::app()->end();
}

This returns {"id":null} to my dialog and no record is created in the database and nothing is logged by Yii. This has worked for a long time and I can't see anything I've done to break it in git logs. What could cause this?

Upvotes: 0

Views: 1711

Answers (5)

Boaz Rymland
Boaz Rymland

Reputation: 1467

Another elusive reason could be an open transaction not being 'committed'. I had such an issue: an open transaction at a previous stage in code run which was not committed, resulted in all changes to the DB reverted once request processing finished (successfully or not - no commit did an implicit rollback).

Heck, even the DB log file showed all 'inserts' correctly. Its only when I also saw in the log 'start transaction' that I've became suspicious, only to affirm my suspicion later while debugging and watching code flow.

Upvotes: 0

Babak Bandpay
Babak Bandpay

Reputation: 177

I know your problem is solved but I think that it can be done better.

Initialize the $model this way if the scenario is insert

$model = new Type;

Initialize the $model this way if the scenario is read, update or delete

$model = Type::model()->findByPk($id);

I had the same issue and I realized that I was doing something wrong which was

$model = Type::model(); /* this is wrong */

Upvotes: 2

Michiel
Michiel

Reputation: 2203

Do you use beforeSave in your model? Then make sure it returns the beforeSave of it's parent:

return parent::beforeSave();

Upvotes: 2

moggizx
moggizx

Reputation: 476

I solved it myself shortly after posting..!

I have added my own constructor in the model but forgot to call the parent constructor at the end. The isNewRecord property's default value is false but is set to true in the constructor that wasn't being run because I had forgotten to call it. This meant it tried to run UPDATE instead of INSERT in save(). So I simply added the call to the parent constructor...

public function __construct($scenario = 'insert')
{
    //some stuff
    parent::__construct($scenario);
}

Don't forget $scenario, it's important... :P

One could argue that Yii should do something if the UPDATE statement does not affect any rows though... :/

Upvotes: 4

Samuel Liew
Samuel Liew

Reputation: 79022

$model->id may not have been populated with the new id with a save().

Use $model->primaryKey instead.

Upvotes: 0

Related Questions