Фрэнки Роберто дал вам хороший ответ.Я просто добавлю некоторую дополнительную информацию.
Сначала простая часть: получение текущей локали в модели .
Если вы установите язык в контроллере как I18n.locale = something
, то вы можете прочитать это в модели таким же образом.В конце концов I18n
является глобальной константой.
Теперь о поиске :
Я обычно предпочитаю проекты, в которых у вас есть одна категория, но названиеКатегория переведена на многие языки.Конструкция, в которой один автомобиль относится к категории «Автомобили», а другой - к «ГИБУЛЕС», ошибочна ИМХО.В последнем случае нет смысла делать его одним сайтом - вы можете создать одноязычное приложение и установить его в нескольких экземплярах, каждый из которых будет переведен на один язык.
Если у вас естьКраткий статический список поддерживаемых языков, вы можете добавить столбец для каждого языка: name_en
, name_fr
, name_pl
.
Если ваш список языков будет большим или неизвестным на моментПри разработке вашего приложения было бы проще сохранить «имя» (приведенное в качестве примера) в виде сериализованного хэша.Таким образом, вы можете получить намеченный перевод как name["fr"]
, name["de"]
и т. Д.
Я уже узнал (трудный путь :-)) , что пользователи обычно слишком ленивыпредоставить все переводы (или они просто не знают всех языков) , поэтому вы должны быть готовы к тому, что некоторые из ваших моделей не будут иметь данные на языке, который вы пытаетесьдля отображения или поиска.
Для каждого «переведенного» атрибута вы можете подготовить метод, который предоставит вам перевод наиболее подходящий в случае, если требуемый отсутствует.
Этот метод может работать аналогично:
def translated_name
([I18n.locale] + other_languages).each do |l|
return name[l] unless name[l].blank?
end
return "" # or some default value - possibly from I18n.t("some.static.default")
end
Конечно, вам не нужно использовать I18n.locale, и вы должны определить other_languages
так, чтобы (в идеале)сопоставить языковые предпочтения пользователя, возможно, путем анализа заголовка «Accept-Language».
Я иногда использую имя метода name_for(lang)
или name_in(lang)
, если мне нужно поддерживать больше языков для данных, чем для интерфейса (которыйЯ переведуи положить в I18n файлы конфигурации).
Ах, да - поиск.:)
Если вы определили «имена» как отдельные атрибуты, вы можете просто выполнить поиск в соответствующем столбце.
Если у вас есть «имена» как один сериализованный хэш, вы можетепоиск в столбце в виде простого текста (однако я не уверен, будет ли YAML искажать символы, не входящие в ASCII) или создать другой столбец с данными для поиска, а затем (на уровне модели,не на уровне SQL) разбить модели на группы: «Строка поиска была найдена на вашем языке», «Строка поиска была найдена на другом языке».Я полагаю, что пользователь многоязыкового сервиса будет доволен результатами поиска, представленными таким образом.