Temporary Entities
Qore\Next\System\Models\TemporaryEntity stores nested form data before it is attached to a real model.
The main user is RepeaterField: a repeater row can be created, edited and upload files before the parent resource form has been saved.
Why It Exists
Nested form rows need an identity before the parent model exists. TemporaryEntity gives each row a UUID and a payload so the frontend can keep editing rows while the parent form is still in progress.
It also implements ModelWithFiles, so nested FileFields can attach uploaded files to a temporary row first.
What The Model Stores
TemporaryEntity stores:
uuidas the stable frontend row identity;nameas the repeater field name;payloadas the nested field values;user_idfor the user creating the row;entity_typeandentity_idafter the parent model is saved;delete_atfor rows that are temporary and can be cleaned up.
The payload and delete_at attributes are cast to array and datetime.
Repeater Flow
When a repeater form opens, RepeaterField returns a nested FormNode for the row fields.
When the row form submits:
- The nested form validates the row payload.
- Qore updates an existing
TemporaryEntityby UUID or creates a new one. - Nested file fields lazily attach files to the temporary entity.
- The response returns
TemporaryEntityJsonResourcewith the row UUID and payload.
When the parent model is saved:
RepeaterFieldreceives the submitted row UUIDs and payloads.- Existing rows for the parent that are no longer submitted are deleted.
- Submitted rows are updated with the final payload.
entity_type,entity_idanddelete_atare updated so the rows belong to the real model.
Using The Value
The value of a repeater field is an array of temporary entities:
RepeaterField::make('contacts')
->setFields(function (Form $form) {
return [
TextField::make('name')->setRules(fn () => ['required', 'string']),
EmailField::make('email')->setRules(fn () => ['nullable', 'email']),
];
});
If those rows should become application-specific models, add a lazy mutator that reads the submitted repeater value after the parent model exists.
Cleanup
Temporary rows use delete_at for abandoned data. Rows become permanent when the parent model save associates them and clears delete_at.
If you add custom temporary workflows, follow the same pattern: set delete_at while the entity is unattached, and clear it only when the data belongs to a real model.