Ruby on Rails 通过请求设置区域设置

示例

在大多数情况下,您可能需要设置I18n区域设置。可能要为当前会话,当前用户或基于URL参数设置区域设置。这可以通过before_action在您的一个控制器中实现或ApplicationController在所有控制器中实现来轻松实现。

class ApplicationController < ActionController::Base
  before_action :set_locale

  protected

  def set_locale
    # 删除不适当/不必要的
    I18n.locale = params[:locale] ||    # 请求参数
      session[:locale] ||               # 本届会议
      (current_user.preferred_locale if user_signed_in?) ||  # 模型保存的配置
      extract_locale_from_accept_language_header ||          # 语言标头-浏览器配置
      I18n.default_locale               # 在您的配置文件中设置,默认为英文
  end

  # 从请求标头中提取语言
  def extract_locale_from_accept_language_header
    if request.env['HTTP_ACCEPT_LANGUAGE']
      lg = request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first.to_sym
      lg.in?([:en, YOUR_AVAILABLE_LANGUAGES]) ? lg : nil
    end
  end

基于URL

该localePARAM可能来自这样一个URL

http://yourapplication.com/products?locale=en

要么

http://yourapplication.com/en/products

要实现后者,您需要编辑routes,添加一个scope:

# config / routes.rb
scope "(:locale)", locale: /en|fr/ do
  resources :products
end

这样,访问http://yourapplication.com/en/products将把您的语言环境设置为:en。相反,访问http://yourapplication.com/fr/products会将其设置为:fr。此外,缺少:locale参数时不会出现路由错误,因为访问http://yourapplication.com/products将加载默认的I18n语言环境。

基于会话或基于持久性

假设用户可以单击按钮/语言标志来更改语言。该操作可以路由到控制器,该控制器将会话设置为当前语言(如果连接了用户,则最终将更改保存到数据库中)

class SetLanguageController < ApplicationController
  skip_before_filter :authenticate_user!
  after_action :set_preferred_locale

  # 通用版本可处理多种语言
  def change_locale
    I18n.locale = sanitize_language_param
    set_session_and_redirect
  end

您必须使用可用语言列表定义sanitize_language_param,并最终在语言不存在的情况下处理错误。

如果您使用的语言很少,则可能值得这样定义它们:

def fr
  I18n.locale = :fr
  set_session_and_redirect
end

def en
  I18n.locale = :en
  set_session_and_redirect
end

private

  def set_session_and_redirect
    session[:locale] = I18n.locale
    redirect_to :back
  end

  def set_preferred_locale
    if user_signed_in?
      current_user.preferred_locale = I18n.locale.to_s
      current_user.save if current_user.changed?
    end
  end
end

注意:不要忘记一些路由添加到您的change_language行为

默认语言环境

请记住,您需要设置应用程序的默认语言环境。您可以通过在以下位置进行设置来实现config/application.rb:

config.i18n.default_locale = :de

或通过在config/initializers文件夹中创建一个初始化程序:

# config / initializers / locale.rb
I18n.default_locale = :it