From 9841a9b03aa18745ef6879f4329480e9c07abd6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sat, 6 Apr 2024 05:18:01 +0200 Subject: [PATCH] Use in_order_of to sort translations by fallback This method was introduced in Rails 7.0, and thanks to it we can simplify the code that gets the translations in order. We tried to use this method to simplify the `Randomizable` concern as well. However, we found out that, when ordering tens of thousands of records, the query could take several minutes, so we aren't using it in this case. Using it for translation fallbacks is OK, since there's a good chance we're never going to have tens of thousands of available locales. Note that automated security tools reported a false positive related to SQL Injection due to the way we used `LEFT JOIN`, so now we get one less false positive in these reports. --- app/models/concerns/globalizable.rb | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/app/models/concerns/globalizable.rb b/app/models/concerns/globalizable.rb index 5578c37db..0ab046c1b 100644 --- a/app/models/concerns/globalizable.rb +++ b/app/models/concerns/globalizable.rb @@ -102,17 +102,11 @@ module Globalizable translations_foreign_key = reflect_on_association(:translations).foreign_key fallbacks = Globalize.fallbacks(Globalize.locale) - fallbacks_with_order = fallbacks.map.with_index do |locale, order| - "('#{locale}', #{order})" - end.join(", ") - translations_ids = translation_class .select("DISTINCT ON (#{translations_foreign_key}) id") .where(locale: fallbacks) - .joins("LEFT JOIN (VALUES #{fallbacks_with_order}) " \ - "AS locales(name, ordering) " \ - "ON locale = locales.name") - .order(translations_foreign_key, "locales.ordering") + .order(translations_foreign_key) + .in_order_of(:locale, fallbacks) with_translations(fallbacks).where("#{translations_table_name}.id": translations_ids) end