I18n :: InvalidLocale Ошибка

Я создаю многоязычное приложение и хочу, чтобы приложение переключалось на язык, установленный в языковых настройках браузера посетителей. Я заметил, что он отлично работает, если языковые настройки соответствуют одной из доступных локалей. Но, к сожалению, как только язык браузера не будет соответствовать одному из языковых стандартов, я получу ошибку I18n :: InvalidLocale ... («es» не является допустимым языковым стандартом), хотя я установил языковой стандарт по умолчанию ...

Что мне не хватает? Как я могу заставить это работать? Есть подсказки?

application.rb

require File.expand_path('../boot', __FILE__)

require 'rails/all'

Bundler.require(*Rails.groups)

module Testapp
  class Application < Rails::Application

    config.i18n.default_locale = :en
    config.i18n.enforce_available_locales = true

    config.active_record.raise_in_transactional_callbacks = true
  end
end

application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  before_action :set_locale

  private

  def extract_locale_from_accept_language_header
    request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first
  end

  def set_locale
    I18n.locale = extract_locale_from_accept_language_header || I18n.default_locale
  end
end

В моем регионе есть файлы de.yml, en.yml и devise.en.yml.

routes.rb

Rails.application.routes.draw do

  scope "(:locale)", locale: /en|de/ do

    root 'welcomes#index'
    devise_for :users
    get "language" => "welcomes#language"

    get "welcomes/download_pdf"

    resources :welcomes do
      get :download, on: :member
    end

    resources :resumes do
      get :download, on: :member
    end

    get '*path' => redirect('/')

  end
end

index.html.erb

<p><%= link_to "EN", root_path(locale: 'en') %></p>
<p><%= link_to "DE", root_path(locale: 'de') %></p>

ОБНОВЛЕНИЕ

Я заметил, что когда я запускаю консоль rails и проверяю I18n.available_locales, это дает мне [: en,: fr,: «zh-CN»,: «zh-TW»,: de] очень странно ?! Поскольку я не установил эти языковые стандарты и их нет в моих приложениях, являются ли эти настройки настройками по умолчанию? Поэтому я полагаю, что необходимы настройки config.i18n.available_locales = [: de,: en].

ОБНОВЛЕНИЕ

Я заметил, что при использовании: config.i18n.enforce_available_locales = false Переводы не работают, но я не получу сообщения об ошибке. Если я обновляю дополнительно в среде / development.rb: config.i18n.fallbacks = true, тогда в моем случае отображается только значение по умолчанию, английский язык, но я не могу изменить его на немецкий.


person trickydiddy    schedule 28.08.2017    source источник


Ответы (4)


config.i18n.enforce_available_locales = true Возможно, это переопределяет поведение локали по умолчанию. Попробуйте отключить его, чтобы можно было использовать языковой стандарт по умолчанию. И предоставьте белый список доступных языковых стандартов, например: config.i18n.available_locales = [:de, :en]

Изменить. Попробуйте сделать это в своем контроллере приложения:

def default_url_options(options = {})
    { locale: I18n.locale }
end
person Sarmad Sabih    schedule 28.08.2017
comment
Если я изменю это, то я не получу сообщения об ошибке, но он ничего не переведет, потому что не получит доступа к языкам. Спасибо за попытку. - person trickydiddy; 28.08.2017
comment
Я отредактировал ответ. Попробуйте добавить белый список доступных языков: config.i18n.available_locales = [:de, :en] - person Sarmad Sabih; 28.08.2017
comment
Отредактируйте ответ еще раз. Попробуй это. - person Sarmad Sabih; 28.08.2017
comment
Нет, он все еще не работает ... возникает ошибка: I18n.locale = extract_locale_from_accept_language_header || I18n.default_locale Я не вижу ничего плохого в этом коде: / - person trickydiddy; 28.08.2017
comment
Что за ошибка? Можете ли вы скопировать ошибку и трассировку стека - person Sarmad Sabih; 28.08.2017
comment
Почему бы вам не установить локальный адрес в URL-адресе, а не в заголовке? - person Sarmad Sabih; 28.08.2017
comment
Позвольте нам продолжить это обсуждение в чате. - person Sarmad Sabih; 28.08.2017

Что-то вроде этого?

def extract_locale_from_accept_language_header
  available_locales = {'de' => 'de', 'en' => 'en'}
  available_locales[request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first]
end
person Vladyslav Sydorenko    schedule 28.08.2017
comment
Ошибка исчезла, но в моем случае это будет только язык по умолчанию, английский ... и я не смогу переключать языки ... спасибо за попытку! - person trickydiddy; 28.08.2017
comment
Я изменил ответ, попробуйте использовать такой хеш, он принимает как строки, так и литералы в качестве ключей. - person Vladyslav Sydorenko; 28.08.2017
comment
К сожалению, проблема не устранена ... ошибка исчезла, но это будет только язык по умолчанию ... я не могу переключать языки, что не имеет никакого смысла ... очень странно ...: / Спасибо за терпение! - person trickydiddy; 28.08.2017
comment
Как именно вы меняете локаль? - person Vladyslav Sydorenko; 28.08.2017
comment
Проверьте мой отредактированный вопрос .. Я использую маршруты, используя область видимости пути. С помощью простого вспомогательного метода link_to для переключения между языками ... www. example.com/en / ... www. example.com/de / ... - person trickydiddy; 28.08.2017
comment
Я думаю, вам нужно изменить локаль в действии индекса и использовать переданные в params one. И, например, сохраните локаль в сеансе. - person Vladyslav Sydorenko; 28.08.2017
comment
Почему? Он работает, если у посетителя такие же языковые настройки, что и у меня ... проблема в том, что гем I18n не переключается на значение по умолчанию, когда нет определенных локалей ... И я не знаю, почему ... : / - person trickydiddy; 28.08.2017

Поскольку вы устанавливаете локаль через заполнитель locale в маршрутах, в вашем application.rb вы также должны разрешить его, используя значение params[:locale], а не заголовок. Итак, в application.rb set_locale должен быть

def set_locale
  I18n.locale = params[:locale] || I18n.default_locale
end

См. Раздел о настройке языкового стандарта из параметров URL здесь, http://guides.rubyonrails.org/i18n.html#configure-the-i18n-module

person Oranagwa Osmond Oscar    schedule 28.08.2017

Возможно, попробуйте это как before_action в контроллере приложения.

  def set_locale
    browser_locale = extract_locale_from_accept_language_header.to_sym
    if I18n.available_locales.include?(browser_locale)
      I18n.locale = browser_locale
    else
      I18n.locale = I18n.default_locale
    end
  end

Затем он должен пытаться установить языковой стандарт, только если он доступен.

person Andrew    schedule 28.08.2017