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');
|
if (!user) throw new Error('User not found');
|
||||||
const character = await FalukantCharacter.findOne({ where: { userId: user.id } });
|
const character = await FalukantCharacter.findOne({ where: { userId: user.id } });
|
||||||
if (!character) throw new Error('Character not found for this user');
|
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 },
|
where: { character1Id: character.id },
|
||||||
attributes: ['createdAt', 'widowFirstName2', 'nextStepProgress'],
|
attributes: ['createdAt', 'widowFirstName2', 'nextStepProgress', 'character2Id', 'relationshipTypeId']
|
||||||
include: [
|
});
|
||||||
{
|
let relationships;
|
||||||
model: FalukantCharacter, as: 'character2',
|
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'],
|
attributes: ['id', 'birthdate', 'gender', 'moodId'],
|
||||||
include: [
|
include: [
|
||||||
{ model: FalukantPredefineFirstname, as: 'definedFirstName', attributes: ['name'] },
|
{ model: FalukantPredefineFirstname, as: 'definedFirstName', attributes: ['name'] },
|
||||||
{ model: TitleOfNobility, as: 'nobleTitle', attributes: ['labelTr'] },
|
{ model: TitleOfNobility, as: 'nobleTitle', attributes: ['labelTr'] },
|
||||||
{ model: CharacterTrait, as: 'traits' },
|
{ model: Mood, as: 'mood' }
|
||||||
{ model: Mood, as: 'mood' },
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{ model: RelationshipType, as: 'relationshipType', attributes: ['tr'] }
|
|
||||||
]
|
]
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
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,
|
createdAt: r.createdAt,
|
||||||
widowFirstName2: r.widowFirstName2,
|
widowFirstName2: r.widowFirstName2,
|
||||||
progress: r.nextStepProgress,
|
progress: r.nextStepProgress,
|
||||||
character2: {
|
character2: c2 ? {
|
||||||
id: r.character2.id,
|
id: c2.id,
|
||||||
age: calcAge(r.character2.birthdate),
|
age: calcAge(c2.birthdate),
|
||||||
gender: r.character2.gender,
|
gender: c2.gender,
|
||||||
firstName: r.character2.definedFirstName?.name || 'Unknown',
|
firstName: c2.definedFirstName?.name || 'Unknown',
|
||||||
nobleTitle: r.character2.nobleTitle?.labelTr || '',
|
nobleTitle: c2.nobleTitle?.labelTr || '',
|
||||||
mood: r.character2.mood,
|
mood: c2.mood,
|
||||||
traits: r.character2.traits
|
traits: c2.traits || []
|
||||||
},
|
} : null,
|
||||||
relationshipType: r.relationshipType.tr
|
relationshipType: type ? type.tr : ''
|
||||||
}));
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
const charsWithChildren = await FalukantCharacter.findAll({
|
const charsWithChildren = await FalukantCharacter.findAll({
|
||||||
where: { userId: user.id },
|
where: { userId: user.id },
|
||||||
include: [
|
include: [
|
||||||
@@ -2927,7 +2958,7 @@ class FalukantService extends BaseService {
|
|||||||
const myChar = user.character;
|
const myChar = user.character;
|
||||||
if (!myChar) throw new Error('Character not found');
|
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({
|
const rel = await Relationship.findOne({
|
||||||
where: {
|
where: {
|
||||||
[Op.or]: [
|
[Op.or]: [
|
||||||
@@ -2935,14 +2966,25 @@ class FalukantService extends BaseService {
|
|||||||
{ character2Id: myChar.id }
|
{ character2Id: myChar.id }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
include: [
|
attributes: ['character1Id', 'character2Id']
|
||||||
{ model: FalukantCharacter, as: 'character1', include: [{ model: CharacterTrait, as: 'traits' }] },
|
|
||||||
{ model: FalukantCharacter, as: 'character2', include: [{ model: CharacterTrait, as: 'traits' }] }
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
if (!rel) throw new Error('Beziehung nicht gefunden');
|
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
|
// 3) Trait-IDs und Mood des relatedChar
|
||||||
const relatedTraitIds = relatedChar.traits.map(t => t.id);
|
const relatedTraitIds = relatedChar.traits.map(t => t.id);
|
||||||
|
|||||||
Reference in New Issue
Block a user