# Generic cloning of a hierarchy

**URL:** <https://community.fibery.io/t/generic-cloning-of-a-hierarchy/6152>\
**Category:** Fibery Showcase\
**Created:** [May 6, 2024, 2:09pm UTC](https://community.fibery.io/t/generic-cloning-of-a-hierarchy/6152 "2024-05-06T14:09:24Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Chr1sG](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/chr1sg/32/3941_2.png) [@Chr1sG](https://community.fibery.io/u/Chr1sG)\
**Post date:** [May 6, 2024, 2:09pm UTC](https://community.fibery.io/t/generic-cloning-of-a-hierarchy/6152/1 "2024-05-06T14:09:24Z")

</div>

Following [a bit of discussion](https://community.fibery.io/t/intra-space-deep-copy/6079) here in the community about duplicating hierarchies of entities, I put together [a space](https://shared.fibery.io/t/ecaa9033-b580-4ea6-a03e-1166a86f1756-deep-clone) which can be used to clone a top-level entity and all its children, grandchildren etc.

At the moment, any items linked via a one-to-many relationship will be cloned (as will any items linked to them via 1:m, and so on…)

m:m, m:1 and 1:1 relations are ignored, with the exception of m:? relations to users (e.g. Assignees, Owner, etc.).

* * *

Once you have installed the space, go to the ‘High level goal’ Objective and find its UUID.  
 ![image](https://us1.discourse-cdn.com/flex020/uploads/fibery/original/2X/b/b0923390cd0d4e57da2b1e08d0de5674f27252b9.png)

Copy this into the UUID cell in the Clones table, and tick the trigger box.

 ![image](https://us1.discourse-cdn.com/flex020/uploads/fibery/original/2X/e/e2dd8e96aeccc8f868560519e3e0b27376be8c4b.png)

You should get a perfect clone of the entire hierarchy from Objective through Project to Tasks.

Now try adding a row to the Clones table with the full name of another database in your workspace, and the UUID of a specific entity in that database, and trigger this one.  
Fingers crossed.

* * *

It’s not been tested thoroughly 😬 so please play with it and provide feedback.

Note: because there is no limit on the depth of cloning, it is possible for it to get stuck in a never ending loop  
e.g. if you have these relations  
Project A → Task 1, Task 2  
Task 1 → Project A, Project B  
and you try to clone Project A, it will never terminate.

If this happens, you’ll need to disable the automation.

---

<div class="post-metadata">

**Author:** ![Matt\_Blais](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/matt_blais/32/1464_2.png) [@Matt\_Blais](https://community.fibery.io/u/Matt_Blais)\
**Post date:** [May 6, 2024, 3:07pm UTC](https://community.fibery.io/t/generic-cloning-of-a-hierarchy/6152/2 "2024-05-06T15:07:58Z")

</div>

> [@Chr1sG](#):
>
> it is possible for it to get stuck in a never ending loop

I would expect the script to terminate with an error message when max script CPU time of 1s is exceeded (or max clock time of 60s).

---

<div class="post-metadata">

**Author:** ![Chr1sG](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/chr1sg/32/3941_2.png) [@Chr1sG](https://community.fibery.io/u/Chr1sG)\
**Post date:** [May 6, 2024, 3:16pm UTC](https://community.fibery.io/t/generic-cloning-of-a-hierarchy/6152/3 "2024-05-06T15:16:45Z")

</div>

> [@Matt\_Blais](#):
>
> I would expect the script to terminate with an error message when max script CPU time of 1s is exceeded (or max clock time of 60s).

I don’t think it will.  
In my template, the script runs, and one of the effects can be to create additional records, and the script then starts to run on these records.  
Each individual script execution is under 60s.

---

<div class="post-metadata">

**Author:** ![Matt\_Blais](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/matt_blais/32/1464_2.png) [@Matt\_Blais](https://community.fibery.io/u/Matt_Blais)\
**Post date:** [May 6, 2024, 4:15pm UTC](https://community.fibery.io/t/generic-cloning-of-a-hierarchy/6152/4 "2024-05-06T16:15:54Z")

</div>

How does that not trigger the dreaded loop detection?

automation script → creates new entity → triggers _same automation_

I had to go to extreme lengths to work around that problem: cloning the _entire tree_ in a single script execution.

---

<div class="post-metadata">

**Author:** ![Chr1sG](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/chr1sg/32/3941_2.png) [@Chr1sG](https://community.fibery.io/u/Chr1sG)\
**Post date:** [May 7, 2024, 9:14am UTC](https://community.fibery.io/t/generic-cloning-of-a-hierarchy/6152/5 "2024-05-07T09:14:46Z")

</div>

> [@New template - Finance money\_bag](https://community.fibery.io/t/new-template-finance/2685/17):
>
> In your case loop should be detected as per algorithm I’ve described above. (Un)Fortunately there is a bug in current implementation, that breaks loop detection for operations called from js scripts. So if you make a change from JS script, that chain I’ve described above is broken and starts anew. Some day I will fix it and your rule will break upside_down_face For scripts we can improve though, and check actual fiberyApi calls from scripts, if they are duplicated in a chain. Cannot promise…

---

<div class="post-metadata">

**Author:** ![Matt\_Blais](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/matt_blais/32/1464_2.png) [@Matt\_Blais](https://community.fibery.io/u/Matt_Blais)\
**Post date:** [May 7, 2024, 3:23pm UTC](https://community.fibery.io/t/generic-cloning-of-a-hierarchy/6152/6 "2024-05-07T15:23:53Z")

</div>

Huh… when loop detection was initially implemented it _broke_ my original cloner system, which worked the same way as what I think you are doing:

> automation script → creates new entity → triggers _same automation_

Now I cannot find the old thread where I complained about that change breaking my original cloner script 🤔

---

<div class="post-metadata">

**Author:** ![IMTanuki](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/imtanuki/32/7751_2.png) [@IMTanuki](https://community.fibery.io/u/IMTanuki)\
**Post date:** [May 9, 2024, 8:30pm UTC](https://community.fibery.io/t/generic-cloning-of-a-hierarchy/6152/7 "2024-05-09T20:30:40Z")

</div>

@Chr1sG - thx for putting this together! I need to do a deep dive over the weekend, but lots of interesting ideas in your code… 😄

Any chance this will make it into the backlog as a std feature?

Will you be extending this to support M:M?

---

<div class="post-metadata">

**Author:** ![Chr1sG](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/chr1sg/32/3941_2.png) [@Chr1sG](https://community.fibery.io/u/Chr1sG)\
**Post date:** [May 9, 2024, 9:30pm UTC](https://community.fibery.io/t/generic-cloning-of-a-hierarchy/6152/8 "2024-05-09T21:30:19Z")

</div>

> [@IMTanuki](#):
>
> Any chance this will make it into the backlog as a std feature?

It’s not planned in the short-term roadmap

> [@IMTanuki](#):
>
> Will you be extending this to support M:M?

Originally, I did include support for m:m, but the method I used can give problems if you try and clone a hierarchy via m:m relations.

Imagine having dbs A, B and C linked  
A 1:m B  
B m:m C

If entity A1 is linked to B1 and B2, which are both linked to entities C1 and C2, the method I created in the template above would cause ‘excessive’ duplication:  
Cloning A1 would trigger cloning of B1 and B2. Cloning of B1 would trigger cloning of C1 and C2, but then so would cloning of B2.

So the resulting new entities would be

A1, B1, C1, C2, B2, C1 and C2

It would be possible to modify the script to add linking to existing entities for m:m relations, but I wasn’t sure how useful this actually would be, apart from relations to users.

---

<div class="post-metadata">

**Author:** ![IMTanuki](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/imtanuki/32/7751_2.png) [@IMTanuki](https://community.fibery.io/u/IMTanuki)\
**Post date:** [May 9, 2024, 11:28pm UTC](https://community.fibery.io/t/generic-cloning-of-a-hierarchy/6152/9 "2024-05-09T23:28:12Z")

</div>

I think the trick would be to maintain a temporary list of all cloned children in a M:M relationship with their respective original/new id’s to avoid the dup you’re describing.

My next step would have been to update my deep copy template to recognize and process fields w/o hard-coding and you’ve basically solved that for me, so I will take a shot at the M"M, hopefully sometime soon.

---

<div class="post-metadata">

**Author:** ![Chr1sG](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/chr1sg/32/3941_2.png) [@Chr1sG](https://community.fibery.io/u/Chr1sG)\
**Post date:** [May 10, 2024, 6:34am UTC](https://community.fibery.io/t/generic-cloning-of-a-hierarchy/6152/10 "2024-05-10T06:34:38Z")

</div>

> [@IMTanuki](#):
>
> I think the trick would be to maintain a temporary list of all cloned children in a M:M relationship with their respective original/new id’s to avoid the dup you’re describing

Yeah, that would be one way, but I was trying to go after a simple method that would scale to any possible hierarchy size.  
Tbh, even with the current method I have, a hierarchy that looks like this

A → B  
B → C  
A → C

could cause problems.

---

<div class="post-metadata">

**Author:** ![IMTanuki](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/imtanuki/32/7751_2.png) [@IMTanuki](https://community.fibery.io/u/IMTanuki)\
**Post date:** [May 10, 2024, 9:00pm UTC](https://community.fibery.io/t/generic-cloning-of-a-hierarchy/6152/11 "2024-05-10T21:00:31Z")

</div>

Haha - why use a simple method, when you can over-engineer it…that’s what I always say… 🤣

Anyway, I was thinking of creating a 2-dim array (dim 1 corresponds to each database, dim 2 for each entity in that db) to track the copied status (of each entity). Then, as you iteratively go thru each entity and clone its immediate children, check the array to see if a new instance of a child has already been created - if not, create it and upd the array, then in both cases, point to the child entity.

This assumes, of course, that you’re cloning a true template with a minimal num of records and not some massive db… 🤣
