Refactor relationship loading in FalukantService: Update logic to load relationships without eager loading, preventing EagerLoadingError. Enhance data retrieval by using separate queries for traits and moods, improving performance and reliability.
This commit is contained in:
@@ -2638,38 +2638,69 @@ class FalukantService extends BaseService {
|
||||
if (!user) throw new Error('User not found');
|
||||
const character = await FalukantCharacter.findOne({ where: { userId: user.id } });
|
||||
if (!character) throw new Error('Character not found for this user');
|
||||
let relationships = await Relationship.findAll({
|
||||
// Load relationships without includes to avoid EagerLoadingError
|
||||
const relRows = await Relationship.findAll({
|
||||
where: { character1Id: character.id },
|
||||
attributes: ['createdAt', 'widowFirstName2', 'nextStepProgress'],
|
||||
include: [
|
||||
{
|
||||
model: FalukantCharacter, as: 'character2',
|
||||
attributes: ['createdAt', 'widowFirstName2', 'nextStepProgress', 'character2Id', 'relationshipTypeId']
|
||||
});
|
||||
let relationships;
|
||||
if (relRows.length === 0) {
|
||||
relationships = [];
|
||||
} else {
|
||||
const typeIds = [...new Set(relRows.map(r => r.relationshipTypeId))];
|
||||
const char2Ids = relRows.map(r => r.character2Id);
|
||||
const [types, character2s] = await Promise.all([
|
||||
RelationshipType.findAll({ where: { id: typeIds }, attributes: ['id', 'tr'] }),
|
||||
FalukantCharacter.findAll({
|
||||
where: { id: char2Ids },
|
||||
attributes: ['id', 'birthdate', 'gender', 'moodId'],
|
||||
include: [
|
||||
{ model: FalukantPredefineFirstname, as: 'definedFirstName', attributes: ['name'] },
|
||||
{ model: TitleOfNobility, as: 'nobleTitle', attributes: ['labelTr'] },
|
||||
{ model: CharacterTrait, as: 'traits' },
|
||||
{ model: Mood, as: 'mood' },
|
||||
]
|
||||
},
|
||||
{ model: RelationshipType, as: 'relationshipType', attributes: ['tr'] }
|
||||
{ model: Mood, as: 'mood' }
|
||||
]
|
||||
})
|
||||
]);
|
||||
const typeMap = Object.fromEntries(types.map(t => [t.id, t]));
|
||||
const char2Map = Object.fromEntries(character2s.map(c => [c.id, c]));
|
||||
const ctRows = await FalukantCharacterTrait.findAll({
|
||||
where: { characterId: char2Ids },
|
||||
attributes: ['characterId', 'traitId']
|
||||
});
|
||||
relationships = relationships.map(r => ({
|
||||
const allTraitIds = [...new Set(ctRows.map(r => r.traitId))];
|
||||
const traitsList = allTraitIds.length
|
||||
? await CharacterTrait.findAll({ where: { id: allTraitIds }, attributes: ['id', 'tr'] })
|
||||
: [];
|
||||
const traitMap = Object.fromEntries(traitsList.map(t => [t.id, t]));
|
||||
const traitsByChar = {};
|
||||
for (const row of ctRows) {
|
||||
if (!traitsByChar[row.characterId]) traitsByChar[row.characterId] = [];
|
||||
const t = traitMap[row.traitId];
|
||||
if (t) traitsByChar[row.characterId].push(t);
|
||||
}
|
||||
for (const c of character2s) {
|
||||
c.setDataValue('traits', traitsByChar[c.id] || []);
|
||||
}
|
||||
const relationships = relRows.map(r => {
|
||||
const c2 = char2Map[r.character2Id];
|
||||
const type = typeMap[r.relationshipTypeId];
|
||||
return {
|
||||
createdAt: r.createdAt,
|
||||
widowFirstName2: r.widowFirstName2,
|
||||
progress: r.nextStepProgress,
|
||||
character2: {
|
||||
id: r.character2.id,
|
||||
age: calcAge(r.character2.birthdate),
|
||||
gender: r.character2.gender,
|
||||
firstName: r.character2.definedFirstName?.name || 'Unknown',
|
||||
nobleTitle: r.character2.nobleTitle?.labelTr || '',
|
||||
mood: r.character2.mood,
|
||||
traits: r.character2.traits
|
||||
},
|
||||
relationshipType: r.relationshipType.tr
|
||||
}));
|
||||
character2: c2 ? {
|
||||
id: c2.id,
|
||||
age: calcAge(c2.birthdate),
|
||||
gender: c2.gender,
|
||||
firstName: c2.definedFirstName?.name || 'Unknown',
|
||||
nobleTitle: c2.nobleTitle?.labelTr || '',
|
||||
mood: c2.mood,
|
||||
traits: c2.traits || []
|
||||
} : null,
|
||||
relationshipType: type ? type.tr : ''
|
||||
};
|
||||
});
|
||||
}
|
||||
const charsWithChildren = await FalukantCharacter.findAll({
|
||||
where: { userId: user.id },
|
||||
include: [
|
||||
@@ -2927,7 +2958,7 @@ class FalukantService extends BaseService {
|
||||
const myChar = user.character;
|
||||
if (!myChar) throw new Error('Character not found');
|
||||
|
||||
// 2) Beziehung finden und „anderen“ Character bestimmen
|
||||
// 2) Beziehung finden und „anderen“ Character bestimmen (ohne Include, um EagerLoadingError zu vermeiden)
|
||||
const rel = await Relationship.findOne({
|
||||
where: {
|
||||
[Op.or]: [
|
||||
@@ -2935,14 +2966,25 @@ class FalukantService extends BaseService {
|
||||
{ character2Id: myChar.id }
|
||||
]
|
||||
},
|
||||
include: [
|
||||
{ model: FalukantCharacter, as: 'character1', include: [{ model: CharacterTrait, as: 'traits' }] },
|
||||
{ model: FalukantCharacter, as: 'character2', include: [{ model: CharacterTrait, as: 'traits' }] }
|
||||
]
|
||||
attributes: ['character1Id', 'character2Id']
|
||||
});
|
||||
if (!rel) throw new Error('Beziehung nicht gefunden');
|
||||
|
||||
const relatedChar = rel.character1.id === myChar.id ? rel.character2 : rel.character1;
|
||||
const relatedCharId = rel.character1Id === myChar.id ? rel.character2Id : rel.character1Id;
|
||||
const relatedChar = await FalukantCharacter.findOne({
|
||||
where: { id: relatedCharId },
|
||||
attributes: ['id', 'moodId']
|
||||
});
|
||||
if (!relatedChar) throw new Error('Related character not found');
|
||||
const ctRows = await FalukantCharacterTrait.findAll({
|
||||
where: { characterId: relatedCharId },
|
||||
attributes: ['traitId']
|
||||
});
|
||||
const traitIds = ctRows.map(r => r.traitId);
|
||||
const traits = traitIds.length
|
||||
? await CharacterTrait.findAll({ where: { id: traitIds }, attributes: ['id'] })
|
||||
: [];
|
||||
relatedChar.setDataValue('traits', traits);
|
||||
|
||||
// 3) Trait-IDs und Mood des relatedChar
|
||||
const relatedTraitIds = relatedChar.traits.map(t => t.id);
|
||||
|
||||
Reference in New Issue
Block a user