For Each Related Record – running commands for every related record¶
The command "For Each Related Record" (menu entry "ForEach Related Record") runs its commands once for every record related to the current record through a relationship. Inside the loop, the related record is the current record. This page is for administrators who build actions that work on the positions, notes or other related records of a record.
1. At a glance¶
| Purpose | Repeat commands for each related record |
| Typical use | Close all open tasks of a project, recalculate the positions of an order, delete closed entries |
| Where in the editor | Toolbar menu "Flow" → "ForEach Related Record" |
| Needs a user interface | No |
| Needs a current record | Yes |
| Changes the current record | Inside the loop only |
| Related | Create Related Record, Update Related Record, Iterate JSON |
2. Settings¶
The settings are on the tab "Settings". Like every command, the command also has "Display Name", "Description" and "Execution Condition" on the tab "General" (see Actions).
| Setting | Meaning | Default / Required |
|---|---|---|
| "Relationship" | A relationship of the current record's entity. The current record is its parent side; the loop runs over the records of its child entity. | Required |
| "Constraint" | Logical expression, evaluated against each related record. Only records for which it is true are processed. Active once a relationship is chosen. | Empty: all related records |
| "Order By" | A field of the child entity the records are sorted by | Empty: the order the records were loaded in |
| "Descending" | Reverses the order | Off |
The commands of the loop are placed on the canvas inside the loop box, between the loop symbol and the exit symbol. Add them with "+" on the arrows inside the box or drag them in.
3. Behaviour¶
- Without a current record, without "Relationship", or if the child entity no longer exists, the action ends (without an error).
- The records related to the current record through the relationship are read.
- "Constraint" is evaluated for each of them (with the variables of the action); the others are left out.
- The remaining records are sorted by "Order By", if set.
- For each record, the commands of the loop run with that record as the current record. They share the variables of the action – a value written in one pass is still there in the next pass and after the loop.
- If a command inside the loop ends the action or fails, the loop stops and the whole action ends the same way. A Jump inside the loop can leave the loop and continue at a command after it.
- After the loop, the record from before the loop is the current record again.
With no matching records, the loop does nothing and the action continues.
Changes made inside the loop are changes of the related records. Save them with Save inside the loop, or "Save" on the command that makes them.
4. Examples¶
Close all open tasks of a project. Action on "Project":
| Setting | Value |
|---|---|
| "Relationship" | Project → Tasks |
| "Constraint" | "Status" ≠ "Done" |
| "Order By" | "Due date" |
Inside the loop: Update Entity Record sets "Status" = "Done" and "Closed on" = today, with "Save" on. A project with 8 tasks, 3 of them done, gets 5 updates.
Sum in a variable. Before the loop, Update Variable sets "Total" to 0. Inside the loop it sets "Total" to "Total + Amount". After the loop, Update Entity Record writes "Total" into the order.
5. Limitations¶
- There is no counter variable for the passes of this loop. Count with a variable as in the example.
- Without "Order By", the order of the records is not defined.
- All related records are read before the loop starts. Records added during the loop are not processed in the same loop.