Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]: Failing to save data for the models after the second level in a chained one-to-one relationship. #16530

Open
thavindu-vetstoria opened this issue Feb 15, 2024 · 0 comments
Labels
bug A bug report status: unverified Unverified

Comments

@thavindu-vetstoria
Copy link

Describe the bug

When there are 3 tables with one-to-one relationship to one and another, first 2 table data are saved in DB but the third ones data is not saved.
In the example, we have Table A, Table B and Table C. Where Table A have one-to-one relationship with Table B, Table B have one-to-one relationship with Table C. We have added the necessary code in Table A and Table B save method. When executed we can see records created for Table A and Table B, but not for the Table C. We encountered this bug when we are migrating to the latest Phalcon version. With Phalcon 4.2 with PHP 7.4, we was able to save data for all 3 tables with this setup.

To Reproduce

We checked the event triggers as in the below sample code, the output is attached as a screenshot and the PDF of the output.
Output.pdf

Steps to reproduce the behavior:

// TableA.php

class TableA extends BaseModel
{
    public $name_a = null;
    public $id_a = null;
    public function initialize()
    {
        $this->setSource('table_a');

        $this->hasOne(
            'id_a',
            TableB::class,
            'id_b',
            [
                'alias' => 'TableB',
                'reusable' => false
            ]
        );
    }

    public function save($data = null, $whiteList = null): bool
    {
        $tbl =  new TableB();
        $this->TableB = $tbl;

        return parent::save($data, $whiteList);
    }
}

//TableB.php

class TableB extends BaseModel
{
    public $name_b = null;
    public $id_b = null;

    public function initialize()
    {
        $this->setSource('table_b');

        $this->hasOne(
            'id_b',
            TableC::class,
            'id_c',
            [
                'alias' => 'TableC',
                'reusable' => false
            ]
        );
    }

    public function save($data = null, $whiteList = null): bool
    {
        $tbl =  new TableC();
        $this->TableC = $tbl;

        return parent::save($data, $whiteList);
    }
}

//TableC.php

class TableC extends BaseModel
{

    public $id_c = null;
    public $name_c = null;
    public function initialize()
    {
        $this->setSource('table_c');
    }
}

//Basemodel.php

abstract class BaseModel extends \Phalcon\Mvc\Model
{

    public function getRelatedRecordsList(): array
    {
        return $this->related;
    }

    public function getDirtyRelated(): array
    {
        return $this->dirtyRelated;
    }

    public function getCollectedRelatedToSave(): array
    {
        return $this->collectRelatedToSave();
    }
}

//index.php

$container = new FactoryDefault();

$container->setShared(
    'modelsManager',
    function () {
        $events_manager = new EventManager();

        $events = [
            'model:validation',
            'model:onValidationFails',
            'model:notSaved',
            'model:prepareSave',
            'model:beforeSave',
            'model:beforeCreate',
            'model:afterSave',
            'model:afterCreate',
            'model:create',
            'model:beforeUpdate',
            'model:update',
            'model:beforeValidate',
            'model:afterValidate',
            'model:save',
        ];

        foreach ($events as $event_name) {
            $events_manager->attach($event_name, function (Event $event, $model) use ($event_name) {
                outputModelInfo($model, $event_name);
                return true;
            });
        }

        $modelsManager = new ModelsManager();
        $modelsManager->setEventsManager($events_manager);

        return $modelsManager;
    }
);

$application = new Application($container);
function outputModelInfo($model, $event)
{
    echo '<pre>';

    $recursivePrint = function ($array, $indent = '') use (&$recursivePrint) {
        foreach ($array as $key => $value) {
            echo $indent . '[' . $key . '] => ';
            if (is_array($value)) {
                echo "Array\n";
                $recursivePrint($value, $indent . '    ');
            } elseif (is_object($value)) {
                echo get_class($value) . " Object\n";
            } else {
                echo $value . "\n";
            }
        }
    };

    $recursivePrint([
        'class' => get_class($model),
        'event' => $event,
        'related' => $model->getRelatedRecordsList(),
        'dirty' => $model->getDirtyRelated(),
        'collected' => $model->getCollectedRelatedToSave(),
    ]);

    echo '</pre>';
}


//IndexController.php

use Phalcon\Mvc\Controller;
use Phalcon\Forms\Element\Text;

class IndexController extends Controller
{
    public function indexAction()
    {
        $tbl = new TableA();
        $tbl->save();
        exit;
    }
}

Expected behavior
When saving the Table A, Table B and Table C, data should be saved in the database.

Screenshots
Screenshot from 2024-02-15 17-25-10

Details

  • Phalcon version: 5.6.1
  • PHP Version: 8.2.15
  • Operating System:Ubuntu 20.04.6 LTS
  • Installation type: installing via package manager
  • Zephir version (if any): 0.18.0
  • Server: Nginx
  • Other related info (Database, table schema): MySQL

Additional context
N/A

@thavindu-vetstoria thavindu-vetstoria added bug A bug report status: unverified Unverified labels Feb 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A bug report status: unverified Unverified
Projects
None yet
Development

No branches or pull requests

1 participant