-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sort by name not working correctly in multilingual project #689
Comments
This should be tagged as bug. |
Good catch. I want to keep translations as eager - they are always needed and using eager loading quite significantly simplifies a bunch of code. Anyway, I think I managed to solve the basic issues by adding the following to the const { columns, translationColumns, alias } = getColumnMetadata(rawConnection, entity);
if (translationColumns.length) {
const languageCode = extendedOptions.ctx?.languageCode || DEFAULT_LANGUAGE_CODE;
const translationsAlias = qb.connection.namingStrategy.eagerJoinRelationAlias(
alias,
'translations',
);
qb.andWhere(`${translationsAlias}.languageCode = :languageCode`, { languageCode });
} However, this does not handle the case in which a translation is missing in a given language. In that case, the item with the missing language is omitted from the result set. I'm having trouble coming up with an SQL query which can handle that, the logic being:
That is beyond my SQL-fu right now. |
Getting closer, with a query like: SELECT "label", "languageCode", "name"
FROM "test_entity" "testentity"
LEFT JOIN
(SELECT * FROM "test_entity_translation" "testentity_translations"
WHERE "testentity_translations"."languageCode" = 'de') t1
ON "t1"."baseId"="testentity"."id" This gives a row for each of the entity, and Update: Unfortunately it seems like there is no way with the existing TypeORM API to join a custom subquery as a relation, see typeorm/typeorm#2074. |
Finally figured out a way to solve that last aspect of the problem. If the current language is not the default, and a translation doesn't exist in that langauge, then it will fall back to the default language. The SQL used in this case looks like (assuming a default LanguageCode of 'en'): WHERE
"testentity_translations"."languageCode" = 'de'
OR
EXISTS (SELECT * FROM "test_entity_translation" WHERE "test_entity_translation"."baseId" = "testentity"."id" AND "test_entity_translation"."languageCode" = 'en')
AND NOT EXISTS (SELECT * FROM "test_entity_translation" WHERE "test_entity_translation"."baseId" = "testentity"."id" AND "test_entity_translation"."languageCode" = 'de') |
Is your feature request related to a problem? Please describe.
List query builder sort's feature on translated properties like "name" of ProductVariant or Product doesn't work correctly, as the query is sorted based on all values, not of the current languageCode from ctx object.
E.g. I have list of products (be the number "ID") in EN:
and their translation in DE:
the result for EN site will wrongly be "Dooh, Arg, Blaigh", and what's worse consequently skip and take stop working it will just return fewer results randomly.
Describe the solution you'd like
In my case I joined translation of wanted language on different alias and sort on it, therefore in core I believe switching translation eager settings to false and in query builder leftjoinselect translation with condition based on current languageCode
qb.leftJoinAndSelect(qb.alias + '.translations', 'translation', 'translation."languageCode" = :langCode', {langCode: ctx.languageCode})
will fix the issue and we will get better performance as a bonus, but mind the need of providing defaults for those that have missing translation
The text was updated successfully, but these errors were encountered: