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

Strange Modesls relations behavior

Hi all. I've faced with very strange situation and I've not found anything about it in documentation. So... We have two models:

<?php

class TestAct extends \Phalcon\Mvc\Model
{

    /**
     *
     * @var integer
     * @Primary
     * @Identity
     * @Column(type="integer", length=11, nullable=false)
     */
    protected $id;

    /**
     *
     * @var string
     * @Column(type="string", length=255, nullable=false)
     */
    protected $active_to;

    /**
     *
     * @var string
     * @Column(type="string", length=255, nullable=false)
     */
    protected $comment;

    /**
     * Method to set the value of field id
     *
     * @param integer $id
     * @return $this
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    /**
     * Method to set the value of field active_to
     *
     * @param string $active_to
     * @return $this
     */
    public function setActiveTo($active_to)
    {
        $this->active_to = $active_to;

        return $this;
    }

    /**
     * Method to set the value of field comment
     *
     * @param string $comment
     * @return $this
     */
    public function setComment($comment)
    {
        $this->comment = $comment;

        return $this;
    }

    /**
     * Returns the value of field id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Returns the value of field active_to
     *
     * @return string
     */
    public function getActiveTo()
    {
        return $this->active_to;
    }

    /**
     * Returns the value of field comment
     *
     * @return string
     */
    public function getComment()
    {
        return $this->comment;
    }

    /**
     * Initialize method for model.
     */
    public function initialize()
    {
        $this->setSchema("chatplugins");
        $this->hasMany('id', 'TestBill', 'act_id', ['alias' => 'TestBill']);
    }

    /**
     * Returns table name mapped in the model.
     *
     * @return string
     */
    public function getSource()
    {
        return 'test_act';
    }

    /**
     * Allows to query a set of records that match the specified conditions
     *
     * @param mixed $parameters
     * @return TestAct[]|TestAct
     */
    public static function find($parameters = null)
    {
        return parent::find($parameters);
    }

    /**
     * Allows to query the first record that match the specified conditions
     *
     * @param mixed $parameters
     * @return TestAct
     */
    public static function findFirst($parameters = null)
    {
        return parent::findFirst($parameters);
    }

    /**
     * Independent Column Mapping.
     * Keys are the real names in the table and the values their names in the application
     *
     * @return array
     */
    public function columnMap()
    {
        return [
            'id' => 'id',
            'active_to' => 'active_to',
            'comment' => 'comment'
        ];
    }

}
<?php

class TestAct extends \Phalcon\Mvc\Model
{

    /**
     *
     * @var integer
     * @Primary
     * @Identity
     * @Column(type="integer", length=11, nullable=false)
     */
    protected $id;

    /**
     *
     * @var string
     * @Column(type="string", length=255, nullable=false)
     */
    protected $active_to;

    /**
     *
     * @var string
     * @Column(type="string", length=255, nullable=false)
     */
    protected $comment;

    /**
     * Method to set the value of field id
     *
     * @param integer $id
     * @return $this
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    /**
     * Method to set the value of field active_to
     *
     * @param string $active_to
     * @return $this
     */
    public function setActiveTo($active_to)
    {
        $this->active_to = $active_to;

        return $this;
    }

    /**
     * Method to set the value of field comment
     *
     * @param string $comment
     * @return $this
     */
    public function setComment($comment)
    {
        $this->comment = $comment;

        return $this;
    }

    /**
     * Returns the value of field id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Returns the value of field active_to
     *
     * @return string
     */
    public function getActiveTo()
    {
        return $this->active_to;
    }

    /**
     * Returns the value of field comment
     *
     * @return string
     */
    public function getComment()
    {
        return $this->comment;
    }

    /**
     * Initialize method for model.
     */
    public function initialize()
    {
        $this->setSchema("chatplugins");
        $this->hasMany('id', 'TestBill', 'act_id', ['alias' => 'TestBill']);
    }

    /**
     * Returns table name mapped in the model.
     *
     * @return string
     */
    public function getSource()
    {
        return 'test_act';
    }

    /**
     * Allows to query a set of records that match the specified conditions
     *
     * @param mixed $parameters
     * @return TestAct[]|TestAct
     */
    public static function find($parameters = null)
    {
        return parent::find($parameters);
    }

    /**
     * Allows to query the first record that match the specified conditions
     *
     * @param mixed $parameters
     * @return TestAct
     */
    public static function findFirst($parameters = null)
    {
        return parent::findFirst($parameters);
    }

    /**
     * Independent Column Mapping.
     * Keys are the real names in the table and the values their names in the application
     *
     * @return array
     */
    public function columnMap()
    {
        return [
            'id' => 'id',
            'active_to' => 'active_to',
            'comment' => 'comment'
        ];
    }

}

Let's insert some data in TestAct

$testAct
            ->setActiveTo('2017-08-06 12:15:16')
            ->setComment(new RawValue(''))->save();

Than to TestBill:

$testBill
            ->setActId(1)
            ->setCount(1)->save();

These records are binded by foreign key(TestBill->act_id with TestAct->id).

Now I want to update TestBill

$testBill = TestBill::findFirst([
            'conditions' => 'act_id = :act_id:',
            'bind' => ['act_id' => addslashes(1)]
        ]);

try {
            $testBill
                ->setCount(22);
            var_dump($testBill->save());
            foreach ($testBill->getMessages() as $message) {
                echo $message;
            }
            die();
        }catch (\Exception $e) {var_dump($e->getMessage());die();}

Everything is good. But... If I do this:

$testBill = TestBill::findFirst([
            'conditions' => 'act_id = :act_id:',
            'bind' => ['act_id' => addslashes(1)]
        ]);
        $id = $testBill->TestAct->getId();
        try {
            $testBill
                ->setCount(22);
            var_dump($testBill->save());
            foreach ($testBill->getMessages() as $message) {
                echo $message;
            }
            die();
        }catch (\Exception $e) {var_dump($e->getMessage());die();}  

I got this: bool(false) comment is required It seems like when I getting some extra data from related model ($id = $testBill->TestAct->getId();) Phalcon remembers state of model and requires records to be filled too. Please, assist in this question. Thanks!

what exactly is the question?

Is it normal behavior of ORM, or is it a bug? And if it is a normal - what should be done to return to upper model?