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

Copying a model with all relations

Hi, I got a question regarding copying a model with all relations. I got a model with multiple relations, and those relations also have relations. Is there a way I can literally copy all those models, as new instances?

To get a clearer image, here is some pseudocode:

$test = Test::Find($id);

$test->testobjects[0]->testgroup->id; //returns  1 for instance

//I want to also copy all relations automatically
$testCopy = new Test($test);
$testCopy->testobjects[0]->testgroup->id //returns 2 for instance

Is there a smart way to do this copy action? Thanks in advance!

Hi,

i think you need to use __clone method. And in this method you should clone all related instances.



43.9k

Hi Karolis, I will give it a try, that look's great !

May I ask why you want to make a complete duplicate of a model? Are you planning on saving it back to the DB as a new record?



43.9k

@Dylan:

I see: an entry duplication where only a fiew fields will be "manualy" changed afterwards

Ah. I'm not aware of any way to clone the object and be able to save it as a new record.



1.3k
Accepted
answer
edited May '18

I've fixed the issue in the end by using a custom recursive function using the ModelManager class. specifically the functions: getRelationRecords and getHasOneAndHasMany . Mind that both functions don't have any documentation.

getHasOneAndHasMany returns an array of Phalcon\Mvc\Model\RelationInterfaces, which you can iterate over and pass to the getRelationRecords function. This function requires 3 parameters, first one is the Phalcon\Mvc\Model\RelationInterface from the array. Second is the method to use (undocumented), leave this null to fetch the records. Last parameter is the model instance of which the relation is.

For n-n connections you could use the Phalcon\Mvc\Model\RelationInterface instance getReferencedFields function, which actually returns a string with the foreign key. For the primary key (which hopefully is just id), you could use getFields, which also just returns a string with the primary key.

Basically the easiest way to iterate over all records and copy them and their deep relations, is to make a recursive function .

edited May '18

Yea, but what's the point of copying it? Like use case? If you want to save it in cache then it's bad idea to save it.



1.3k

Yea, but what's the point of copying it? Like use case? If you want to save it in cache then it's bad idea to save it.

I don't want to save it in the cache, i want to save it in the database, with a reference to the original model instance. This way I can keep all original data intact.

In my use, I have some static relations (states etc) which I do not copy. But all the instanced relations (1-1, 1-n, n-n) need to be copied.



2.5k
edited Jan '19

Could you share your code? I also have a use case for it

I've fixed the issue in the end by using a custom recursive function using the...