cphalcon
cphalcon copied to clipboard
[BUG]: Cannot store multiple changed relation values
The bug When trying to store multiple relations, only the last set value is stored.
To Reproduce
use Phalcon\Db\Adapter\Pdo\Sqlite;
use Phalcon\Db\Column;
use Phalcon\Db\Index;
use Phalcon\Di;
use Phalcon\Mvc\Model;
$di = new Di();
$db = new Sqlite(["dbname" => ":memory:"]);
$di->set('db', $db);
$di->set('modelsManager', new Model\Manager());
$di->set('modelsMetadata', new Model\MetaData\Memory());
Di::setDefault($di);
$db->createTable('person', '', [
'columns' => [
new Column('id', ['type' => Column::TYPE_INTEGER, 'size' => 11, 'notNull' => true]),
new Column('name', ['type' => Column::TYPE_VARCHAR, 'size' => 255, 'notNull' => true]),
],
'indexes' => [new Index('PRIMARY', ['id'])],
]);
$db->createTable('person_hair', '', [
'columns' => [
new Column('person_id', ['type' => Column::TYPE_INTEGER, 'size' => 11, 'notNull' => true]),
new Column('color', ['type' => Column::TYPE_VARCHAR, 'size' => 255, 'notNull' => true]),
new Column('length', ['type' => Column::TYPE_VARCHAR, 'size' => 255, 'notNull' => true]),
],
'indexes' => [new Index('PRIMARY', ['person_id'])],
]);
class Person extends Model
{
public function initialize()
{
$this->setSource('person');
$this->hasOne('id', PersonHair::class, 'person_id', ['alias' => 'hair']);
}
}
class PersonHair extends Model
{
public function initialize()
{
$this->setSource('person_hair');
}
}
$db->insert('person', [1, 'Tim Cook'], ['id', 'name']);
$db->insert('person_hair', [1, 'Black', 'Long'], ['person_id', 'color', 'length']);
$timCook = Person::findFirst(1);
echo $timCook->name . ' : ' . $timCook->hair->color . ' : ' . $timCook->hair->length . PHP_EOL;
$timCook->hair->color = 'Gray';
$timCook->hair->length = 'Short';
$timCook->save();
$timCook2 = Person::findFirst(1);
echo $timCook2->name . ' : ' . $timCook2->hair->color . ' : ' . $timCook2->hair->length . PHP_EOL;
Output
Tim Cook : Black : Long
Tim Cook : Black : Short
Expected output
Tim Cook : Black : Long
Tim Cook : Gray : Short
Details
- Phalcon version: 4.1.0
- PHP Version: 7.2.34
- Operating System: MacOS
- Installation type: Compiling from source / Cloudlinux
- Server: Apache
Additional context This problem occurs in 4.1.0 but not in 3.4.5
I think you need to add "reusable => true" to hasOne after the alias. This seems to be an undocumented thing especially if upgrading from 3.4.5
@rtiagom that did it, thanks a lot!
Would indeed be nice if this was added here: https://docs.phalcon.io/4.0/nl-nl/upgrade
Edit: The problem still occurs in belongsTo relations, see: https://github.com/phalcon/cphalcon/issues/15572
The reusable parameter has been present in the framework in v3 and later and is used to cache relations to avoid db calls.
In the docs: https://docs.phalcon.io/4.0/en/db-models-relationships#caching
This needs to be looked at. It should work either way, whether you have reusable or not.
I will need to write a test with the above information so that I can reproduce it and then start tracing it.
I also had a problem when upgrading to v4 from v3.4.5. It didn't save unless reusable was used
Any news on this? It's a pretty big issue.
@krazzer Be careful with reusable set to true. It caches the related model.
@krazzer @rtiagom Is this still an issue.
I checked and we have a test for this that is passing here:
https://github.com/phalcon/cphalcon/blob/5.0.x/tests/database/Mvc/Model/SaveCest.php#L189
Let me know please.
@niden unfortunately the output is still the same in 5.1.1.
See updated code here: https://gist.github.com/krazzer/481efdf00ff886a35baab5b43f705923
I will check it again @krazzer