cphalcon icon indicating copy to clipboard operation
cphalcon copied to clipboard

[BUG]: Cannot store multiple changed relation values

Open krazzer opened this issue 4 years ago • 10 comments

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

krazzer avatar Jun 24 '21 09:06 krazzer

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

rtmotiondev avatar Jun 29 '21 13:06 rtmotiondev

@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

krazzer avatar Jul 02 '21 07:07 krazzer

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.

niden avatar Jul 02 '21 13:07 niden

I will need to write a test with the above information so that I can reproduce it and then start tracing it.

niden avatar Jul 02 '21 13:07 niden

I also had a problem when upgrading to v4 from v3.4.5. It didn't save unless reusable was used

rtmotiondev avatar Jul 05 '21 09:07 rtmotiondev

Any news on this? It's a pretty big issue.

rtmotiondev avatar Jul 08 '21 10:07 rtmotiondev

@krazzer Be careful with reusable set to true. It caches the related model.

rtmotiondev avatar Jul 11 '21 09:07 rtmotiondev

@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 avatar Nov 02 '22 14:11 niden

@niden unfortunately the output is still the same in 5.1.1.

See updated code here: https://gist.github.com/krazzer/481efdf00ff886a35baab5b43f705923

krazzer avatar Nov 15 '22 10:11 krazzer

I will check it again @krazzer

niden avatar Nov 15 '22 23:11 niden