From d23026121e60dc8b41a6a54033bd20ec8204ed0e Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Wed, 4 Feb 2026 15:16:05 +0100 Subject: [PATCH] Refactor child character loading in FalukantService: Update logic to load child relations using separate queries, improving performance and preventing EagerLoadingError. Simplify data retrieval by eliminating unnecessary eager loading and enhancing clarity in the code structure. --- backend/services/falukantService.js | 79 ++++++++++++++--------------- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/backend/services/falukantService.js b/backend/services/falukantService.js index 6ecdcef..a3841c5 100644 --- a/backend/services/falukantService.js +++ b/backend/services/falukantService.js @@ -2701,50 +2701,45 @@ class FalukantService extends BaseService { }; }); } - const charsWithChildren = await FalukantCharacter.findAll({ + // Load child relations without FalukantCharacter includes to avoid EagerLoadingError + const userCharacterIds = (await FalukantCharacter.findAll({ where: { userId: user.id }, - include: [ - { - model: ChildRelation, - as: 'childrenFather', - include: [{ - model: FalukantCharacter, - as: 'child', - include: [{ model: FalukantPredefineFirstname, as: 'definedFirstName', attributes: ['name'] }] - }] + attributes: ['id'] + })).map(c => c.id); + const childRels = userCharacterIds.length + ? await ChildRelation.findAll({ + where: { + [Op.or]: [ + { fatherCharacterId: { [Op.in]: userCharacterIds } }, + { motherCharacterId: { [Op.in]: userCharacterIds } } + ] }, - { - model: ChildRelation, - as: 'childrenMother', - include: [{ - model: FalukantCharacter, - as: 'child', - include: [{ model: FalukantPredefineFirstname, as: 'definedFirstName', attributes: ['name'] }] - }] - } - ] + attributes: ['childCharacterId', 'nameSet', 'isHeir', 'createdAt'] + }) + : []; + const childCharIds = [...new Set(childRels.map(r => r.childCharacterId))]; + const childChars = childCharIds.length + ? await FalukantCharacter.findAll({ + where: { id: childCharIds }, + attributes: ['id', 'birthdate', 'gender'], + include: [{ model: FalukantPredefineFirstname, as: 'definedFirstName', attributes: ['name'] }] + }) + : []; + const childCharMap = Object.fromEntries(childChars.map(c => [c.id, c])); + const children = childRels.map(rel => { + const kid = childCharMap[rel.childCharacterId]; + return { + childCharacterId: rel.childCharacterId, + name: kid?.definedFirstName?.name || 'Unknown', + gender: kid?.gender, + age: kid?.birthdate ? calcAge(kid.birthdate) : null, + hasName: rel.nameSet, + isHeir: rel.isHeir || false, + _createdAt: rel.createdAt, + }; }); - const children = []; - for (const parentChar of charsWithChildren) { - const allRels = [ - ...(parentChar.childrenFather || []), - ...(parentChar.childrenMother || []) - ]; - for (const rel of allRels) { - const kid = rel.child; - children.push({ - childCharacterId: kid.id, - name: kid.definedFirstName?.name || 'Unknown', - gender: kid.gender, - age: calcAge(kid.birthdate), - hasName: rel.nameSet, - isHeir: rel.isHeir || false, - _createdAt: rel.createdAt, - }); - } - } - // Sort children globally by relation createdAt ascending (older first) - children.sort((a, b) => new Date(a._createdAt) - new Date(b._createdAt)); + // Sort children globally by relation createdAt ascending (older first) + children.sort((a, b) => new Date(a._createdAt) - new Date(b._createdAt)); const inProgress = ['wooing', 'engaged', 'married']; const family = { relationships: relationships.filter(r => inProgress.includes(r.relationshipType)), @@ -2968,7 +2963,7 @@ class FalukantService extends BaseService { }, attributes: ['character1Id', 'character2Id'] }); - if (!rel) throw new Error('Beziehung nicht gefunden'); + if (!rel) return []; const relatedCharId = rel.character1Id === myChar.id ? rel.character2Id : rel.character1Id; const relatedChar = await FalukantCharacter.findOne({