MCPcopy
hub / github.com/directus/directus / processO2M

Method processO2M

api/src/services/payload.ts:765–1076  ·  view source on GitHub ↗

* Recursively save/update all nested related o2m items

(
		data: Partial<Item>,
		parent: PrimaryKey,
		opts?: MutationOptions,
	)

Source from the content-addressed store, hash-verified

763 * Recursively save/update all nested related o2m items
764 */
765 async processO2M(
766 data: Partial<Item>,
767 parent: PrimaryKey,
768 opts?: MutationOptions,
769 ): Promise<PayloadServiceProcessRelationResult> {
770 const revisions: PrimaryKey[] = [];
771 let userIntegrityCheckFlags = UserIntegrityCheckFlag.None;
772
773 const nestedActionEvents: ActionEventParams[] = [];
774
775 const relations = this.schema.relations.filter((relation) => {
776 return relation.related_collection === this.collection;
777 });
778
779 const payload = cloneDeep(data);
780
781 // Only process related records that are actually in the payload
782 const relationsToProcess = relations.filter((relation) => {
783 if (!relation.meta?.one_field) return false;
784 return relation.meta.one_field in payload;
785 });
786
787 const nestedUpdateSchema = Joi.object({
788 create: Joi.array().items(Joi.object().unknown()),
789 update: Joi.array().items(Joi.object().unknown()),
790 delete: Joi.array().items(Joi.string(), Joi.number()),
791 });
792
793 for (const relation of relationsToProcess) {
794 if (!relation.meta) continue;
795
796 const currentPrimaryKeyField = this.schema.collections[relation.related_collection!]!.primary;
797 const relatedPrimaryKeyField = this.schema.collections[relation.collection]!.primary;
798
799 const { getService } = await import('../utils/get-service.js');
800
801 const service = getService(relation.collection, {
802 accountability: this.accountability,
803 knex: this.knex,
804 schema: this.schema,
805 nested: [...this.nested, relation.meta!.one_field!],
806 });
807
808 const recordsToUpsert: Partial<Item>[] = [];
809 const savedPrimaryKeys: PrimaryKey[] = [];
810
811 // Nested array of individual items
812 const field = payload[relation.meta!.one_field!];
813
814 if (!field || Array.isArray(field)) {
815 const updates = field || []; // treat falsey values as removing all children
816
817 for (let i = 0; i < updates.length; i++) {
818 const currentId = parent || payload[currentPrimaryKeyField];
819 const relatedRecord = updates[i];
820
821 const relatedId =
822 typeof relatedRecord === 'string' || typeof relatedRecord === 'number'

Callers 2

createOneMethod · 0.95
updateManyMethod · 0.95

Calls 8

getServiceFunction · 0.85
stringMethod · 0.80
fromMethod · 0.80
upsertManyMethod · 0.65
deleteByQueryMethod · 0.65
updateByQueryMethod · 0.65
createManyMethod · 0.65
updateOneMethod · 0.65

Tested by

no test coverage detected