active-record
active-record copied to clipboard
\yii\db\BaseActiveRecord::save() returns false if \PDOStatement::rowCount() is falsy after insert
Docs for \yii\db\BaseActiveRecord::save()
@return boolean whether the saving succeeded (i.e. no validation errors occurred)
As far as I can tell there are three ways that it can return false
- validation fails
beforeSave()returnsfalse- after an INSERT command is executed,
\PDOStatement::rowCount()is falsy, e.g. integer zero. (This branch is only on insert and does not exist ifsave()callsupdate()).
It seems to me that an INSERT command that executes without an exception but that affects zero rows is an exceptional condition that the app will want to handle differently from validation failure or beforeSave() returning false. If this happens I would probably want to rollback the transaction. But it can be complicated for the app code to discriminate this condition and throw an exception.
If \yii\db\Schema::insert would instead throw an exception then application scripts can more easily deal with save() returning false. Validation and beforeSave() are entirely the app's responsibility. Zero rows affected after insert, otoh, is very weird and better processed via an exception.
It's unusual for false return in the Yii 2 API to be so ambiguous.
Porposal: change \yii\db\Schema::insert to throw an exception if !$command->execute().
Could be done in 2.1.
What can cause \PDOStatement::rowCount() to return zero after an INSERT command is executed successfully?
I see no reason for that if PDO driver is implemented correctly.