Skip to main content

i18n Rails: полное руководство по интернационализации Ruby on Rails

От первого файла локали до рабочей среды: настройте Rails I18n, используйте вспомогательную функцию t(), обработайте формы множественного числа CLDR, исправьте распространённые ошибки и добавьте умные цепочки резервных локалей.

1

Разобраться в архитектуре Rails I18n

Rails поставляется со встроенным пакетом I18n. Файлы перевода находятся в config/locales/ в формате YAML по умолчанию или Ruby. Фреймворк предоставляет вспомогательную функцию t(), псевдоним I18n.translate, в представлениях, контроллерах, моделях и почтовых службах. Rails I18n намеренно прост и сразу обрабатывает базовый перевод, интерполяцию и формы множественного числа.

config/application.rb
# Rails includes i18n out of the box via the i18n gem
# config/application.rb
module MyApp
  class Application < Rails::Application
    # Default locale
    config.i18n.default_locale = :en

    # Available locales
    config.i18n.available_locales = [:en, :de, :ja, :es, :fr, :'pt-BR']

    # Fallback to default locale when translation is missing
    config.i18n.fallbacks = true

    # Load translations from nested directories
    config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
  end
end
config/routes.rb
# config/routes.rb
Rails.application.routes.draw do
  scope "/:locale", locale: /en|de|ja|es|fr|pt-BR/ do
    root "home#index"
    resources :products
  end

  root "home#index"
end

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  around_action :switch_locale

  private

  def switch_locale(&action)
    locale = params[:locale] || I18n.default_locale
    I18n.with_locale(locale, &action)
  end

  def default_url_options
    { locale: I18n.locale }
  end
end
Rails автоматически загружает все файлы .yml и .rb из config/locales/. Их можно организовать по языку (en.yml, de.yml), функции (en/users.yml, en/orders.yml) или обоими способами (en/users.yml, de/users.yml). Rails объединяет все файлы при запуске.
2

Настроить параметры локали

Задайте default_locale, available_locales и резервное поведение в config/application.rb или инициализаторе. Настройте определение локали в ApplicationController с помощью before_action, чтобы получать её из URL, сеанса, cookie или заголовка Accept-Language.

config/locales/en.yml
# config/locales/en.yml
en:
  nav:
    home: "Home"
    about: "About"
    settings: "Settings"
  greeting: "Hello, %{name}!"
  cart:
    item_count:
      one: "%{count} item"
      other: "%{count} items"

# config/locales/de.yml
de:
  nav:
    home: "Startseite"
    about: "Über uns"
    settings: "Einstellungen"
  greeting: "Hallo, %{name}!"
  cart:
    item_count:
      one: "%{count} Artikel"
      other: "%{count} Artikel"
Задание I18n.locale в before_action безопасно для отдельного запроса, а изменение I18n.default_locale во время выполнения является глобальным и влияет на все потоки. Для изменений локали в запросе всегда используйте локальный для потока I18n.locale, а не I18n.default_locale.
3

Использовать вспомогательную функцию t()

Вспомогательная функция t() доступна во всём Rails: представлениях, контроллерах, моделях, почтовых службах и заданиях. Она принимает ключ, необязательные переменные интерполяции и такие параметры, как стандартные значения и область. В представлениях Rails поддерживает отложенные поиски, автоматически ограничивающие ключи текущими контроллером и действием.

app/views/example.html.erb
# In views (ERB)
<h1><%= t('nav.home') %></h1>
<p><%= t('greeting', name: @user.name) %></p>

# In controllers
flash[:notice] = t('flash.product_created')

# In models
validates :name, presence: { message: I18n.t('errors.blank') }

# With HTML (safe)
<%= t('terms_html', link: link_to(t('terms_link'), '/terms')) %>
4

Обработать формы множественного числа

Rails I18n использует категории множественного числа CLDR: zero, one, two, few, many, other. Английскому нужны только one и other, но другим языкам требуется больше форм. Определите переводы множественного числа как вложенные ключи YAML для категорий целевых языков.

Plural forms
# In YAML:
en:
  cart:
    item_count:
      zero: "No items"
      one: "%{count} item"
      other: "%{count} items"

# Arabic (6 forms):
ar:
  cart:
    item_count:
      zero: "لا عناصر"
      one: "عنصر واحد"
      two: "عنصران"
      few: "%{count} عناصر"
      many: "%{count} عنصرًا"
      other: "%{count} عنصر"

# Usage in views:
<%= t('cart.item_count', count: @cart.items.size) %>
Rails создаёт I18n::InvalidPluralizationData, если в активной локали отсутствует необходимая категория. Если русская локаль определяет только one и other, скопированные из английского, количества 2, 3 и 4 вызовут сбой, поскольку русскому нужна few. Всегда определяйте все категории CLDR каждого языка.
5

Добавить цепочки резервных локалей

Встроенный I18n.fallbacks в Rails предоставляет только базовый переход от региональной к стандартной локали. Пользователь pt-BR при отсутствии ключа видит английский вместо pt-PT. rails-locale-chain добавляет настраиваемые цепочки глубокого объединения, чтобы региональные пользователи всегда видели ближайший доступный перевод.

Lazy lookups
# Lazy lookups use the controller/action as scope
# app/views/products/index.html.erb
# Instead of t('products.index.title'), just use:
<h1><%= t('.title') %></h1>
<p><%= t('.description') %></p>

# Rails looks up: products.index.title and products.index.description

# config/locales/en.yml
en:
  products:
    index:
      title: "All Products"
      description: "Browse our catalog"
rails-locale-chain включает более 75 резервных цепочек для 11 языковых семейств. Добавьте его в Gemfile, настройте в инициализаторе, и региональные пользователи сразу увидят переводы родительской локали вместо пробелов на английском.
6

Автоматизировать перевод

После завершения настройки Rails I18n переведите файлы локалей YAML с помощью ИИ. i18n Agent изначально поддерживает YAML: укажите исходный файл локали, и он создаст все целевые языки, сохраняя вложенные ключи, переменные интерполяции и формы множественного числа.

config/initializers/locale_chain.rb
# Gemfile
gem 'rails-locale-chain'

# config/initializers/locale_chain.rb
Rails.application.config.i18n.fallbacks = {
  'pt-BR': ['pt', 'en'],
  'zh-Hant-TW': ['zh-Hant', 'zh', 'en'],
  'es-419': ['es', 'en'],
}

# The gem deep-merges translations across the chain
# pt-BR -> pt -> en
# Missing keys in pt-BR are filled from pt, then en
Переводите постепенно: добавив новые ключи, переведите только различия. Это сохранит существующие переводы и избавит от повторного создания неизменённых строк.

Распространённые ошибки

Ошибки InvalidPluralizationData

Rails аварийно завершается с I18n::InvalidPluralizationData, если отсутствует необходимая категория множественного числа CLDR. Чаще всего это происходит, когда английские формы one/other копируют в языки, которым нужно больше категорий: русскому требуется few, арабскому — zero/two/few/many. Установите rails-i18n для правильных правил CLDR и определите все категории.

Отложенные поиски вне представлений

Отложенные поиски (t('.key')) работают только в представлениях, где Rails знает контроллер и действие. Использование t('.key') в модели, почтовой службе или объекте службы возвращает ошибку отсутствующего перевода. Вне представлений применяйте полные ключи (t('users.show.key')).

Синтаксические ошибки YAML нарушают все переводы

Одна синтаксическая ошибка YAML — неверный отступ, специальный символ без кавычек или табуляция вместо пробелов — предотвращает загрузку всего файла локали. Все его переводы возвращают ошибки отсутствующих ключей. Проверяйте YAML в CI с помощью линтера и заключайте в кавычки строки с двоеточиями, скобками или начальными специальными символами.

Попробовать i18n Agent

Перетащите сюда файл перевода

JSON, YAML, PO, XML, CSV, Markdown, Properties

или нажмите, чтобы выбрать

Целевые языки

Регистрация не требуетсяМгновенный расчёт

Частые вопросы об i18n Rails