I've been building out a fairly large project using Phalcon 4.0.5 and just hit a major snag.
Our models in some cases are dynamic, so we will create an instance, and set the source table after creation, which has been working fine until its done recursively, here is an example:
class DynamicModel extends \Phalcon\Mvc\Model
{
public function setTable($table)
{
$this->setSource($table);
}
}
$originalModel = new \Model\DynamicModel;
$originalModel->setTable('original');
$originalModel::find();
This all works great, until...
class DynamicModel extends \Phalcon\Mvc\Model
{
public function setTable($table)
{
$this->setSource($table);
}
public function afterFetch(): void
{
$someOtherTable = new \Model\DynamicModel;
$someOtherTable->setTable('some_new_table');
// this works, but now the source for any instance
// of \Model\DyanmicModel is 'some_new_table'
$someOtherTable::find();
}
}
I can use this line to fix the issue of it having the wrong table, and force it to refresh in setTable()
$this->getModelsManager()->__destruct();
But the issue remains for saving it... for example:
$originalModel = new \Model\DynamicModel;
$originalModel->setTable('original');
$originalModel::find();
this fires afterFetch() and changes table to some_new_table
So now when you go to save the model instance like:
$originalModel->some_field = 123;
$originalModel->save();
Its now trying to save to some_new_table
I've tried a number of different approaches to overcome this, the most promising seems to be anonymously subclassing DynamicModel, which seems to work until you try to run a query.
$dynamicModelAnonymousClassInstance = new class extends \Model\DynamicModel {
public function initialize(): void
{
$this->setSource('some_other_table');
parent::initialize();
}
};
With the above, $dynamicModelAnonymousClassInstance
appears to be a perfectly usable model, but when you run ::find()
you get:
Scanning error before 'anonymous...' when parsing: SELECT [email protected] (155)
So it seems to discard the source
set behind the scenes, but only once you try to do a query. I'm not sure if that is a bug, or I'm just not using it as intended so its behaving unpredictably.
When I define the class normally, for instance:
class SomeOtherTable extends \Model\ManagedModel {
public function initialize(): void
{
$this->setSource('some_other_table');
parent::initialize();
}
};
\Model\SomeOtherTable::find();
This works fine, but the problem is I can't predefine the names of the classes on the filesystem for this project, I need to be able to generate them dynamically by the name provided by the user.
I would really appreciate any ideas on how to overcome the issue, or other approaches that might avoid the issue altogether.
Thanks