Yii2: ActiveRecord::update() for new model does not work

Created on 19 May 2016  路  5Comments  路  Source: yiisoft/yii2

Assuming User represents an ActiveRecord model for DB table user with PK id.

$user = new User();
$user->id = 123;
$user->name = 'Test';
$user->update(false, ['name']);

The example above generates the following (wrong) SQL:

UPDATE `user` SET `name`='Test' WHERE `id` IS NULL

Expected SQL:

UPDATE `user` SET `name`='Test' WHERE `id`=123

Doing $user->setOldAttribute('id', 123) instead of $user->id = 123; to make update() generate correct SQL seems to be too cryptic.

Most helpful comment

The title is not good, you are not trying to update a new model but you are trying to update an existing model without telling yii that it does exist.
How about this:

$user = new User();
$user->id = 123;
$user->isNewRecord = false;
$user->name = 'Test';
$user->update(false, ['name']);

All 5 comments

This would be complete gutting of the active record paradigm, why are you not finding the document first? Or even performing a ::updateAll()?

@Sammaye

why are you not finding the document first?

Why not? For ex., the ID comes as a number from trusted source, no need to check for existence in DB with find() first. Or maybe I did the find() but used asArray() to lower memory usage/other reasons and now only have ID as a number.

Or even performing a ::updateAll() ?

Now that I didn't think about - its a nice workaround for the problem (of more easily building UPDATE statement without writing raw SQL myself when ID number of record is known).

In this case updateAll would be the preferred way and should be faster too

The title is not good, you are not trying to update a new model but you are trying to update an existing model without telling yii that it does exist.
How about this:

$user = new User();
$user->id = 123;
$user->isNewRecord = false;
$user->name = 'Test';
$user->update(false, ['name']);

It is by design. I don't think that we have to change anything.

Was this page helpful?
0 / 5 - 0 ratings