We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Phalcon 4 Bug? No updates for relations possible

I'm trying to update my app to phalcon 4, but it seems that we're no longer able to update values of relations. Even if I just print the value, it's reseted. The only way seemts to create new objects and clone the data to handle updates of relations.

Is there a way to handle this without recreation my models?

i also created a simple example via phalcon devtools to show you my problem:

class IndexController extends ControllerBase
{
    public function indexAction()
    {
        $product = Product::findFirst();

        $product->price->amount = 1337;
        // this will print 100 ?!?? (100 is the value of the database)
        echo $product->price->amount;
        exit;
    }
}

Here are my models:

namespace marvas;

class Product extends \Phalcon\Mvc\Model
{
    public $productId;
    public $priceId;
    public $name;

    public function initialize()
    {
        $this->setSchema("test");
        $this->setSource("product");
        $this->belongsTo('priceId', 'marvas\Price', 'priceId', ['alias' => 'Price']);
    }
}

-

namespace marvas;

class Price extends \Phalcon\Mvc\Model
{
    public $priceId;
    public $amount;

    public function initialize()
    {
        $this->setSchema("test");
        $this->setSource("price");
        $this->hasOne('priceId', 'marvas\Product', 'priceId', ['alias' => 'Product']);
    }
}
edited Jul '20

Try marking the relation as reusable:

        $this->belongsTo('priceId', 'marvas\Price', 'priceId', ['alias' => 'Price', 'reusable' => true]);

I also read about this new option, but the docs only says:

by doing so, we tell the ORM to automatically reuse the records from memory instead of re-querying them again and again

Anyway, I tried it and now the value in my example is not reseted immediately anymore. Therefore the output is 1337 now (in my example above). Unfortunately the value is still not updated in the database if I try to save the product:

It seems the value will be only in the memory.

This will output 555 (but the name of the product is also saved in the database):

public function indexAction()
{
    $product = Product::findFirst();
    $product->name = "test555";
    $product->price->amount = 555;
    $product->save();

    $product = Product::findFirst();
    echo $product->price->amount;
    exit;
}

This will ouput 100 again (which is still the value of the database)

public function indexAction()
{
    $product = Product::findFirst();
    echo $product->price->amount;
    exit;
}

I've always found updating related models to be cumbersome. I usually resort to setting the relation to a "new" object.

$product = Product::findFirst();
$product->name = "test555";
$price = $product->price; // May need"  $price = clone $product->price ".  I can't remember.
$price->amount = 555;
$product->price = $price; // re-assign the whole object.
$product->save();
edited Jul '20

That does not work either, even with the clone keyword, the value is not updating.

As I understand the behavior correct, it's because Phalcon 4 always selects the values from the database. I don't know why this should be good idea, except of some race conditions, because even the smallest selects are unnecessary overhead. So somebody invented the new reusable param, which have to be set on all relation initializations to avoid this behavior.

So we have the worst of 3 worlds:

  • Breaking old features without any information on upgrade guide or at least while coding. It's total confusing that values are reseted and there are no warnings or other information.
  • Overhead because of selecting columns all the time to get values, which are already there.
  • To make the confusing complete: When using reusable param, we are able to change and reload models and they seem to be correct, but they are only correct in the memory. (So my unit tests would say, it's fine, but it's a lie.)

So currently it seems there is no way for me to upgrade on phalcon 4. I used MANY relations in my project. Evertime creating new models, temporary saving old data and assign again is to weird to handle.

My personal wish is the old behavior to update models - and I would definitly say: That's a bug!

Having the same problem here. This issue is casuing major problems for us. We have been working on our upgrade to 4 for over a month now....

Thanks, this solved the issue for me while upgrading from 3.4 to 4.0.6. Though it would be nice if it was mentiond on https://docs.phalcon.io/4.0/en/upgrade.

Try marking the relation as reusable:

       $this->belongsTo('priceId', 'marvas\Price', 'priceId', ['alias' => 'Price', 'reusable' => true]);