如何在注销时从URL确定Rails应用程序和登录时的用户配置文件?

时间:2016-05-09 19:54:23

标签: ruby-on-rails internationalization rails-i18n

我正在尝试在RailsTutorial示例应用程序上实现国际化。

我设法为每个用户存储区域设置属性,以及myurl.com/enmyurl.com/es等网址本地化。关键是如何在用户注销时将两种方法结合起来并将我的应用程序国际化为URL params,否则请使用他自己的偏好。

到目前为止,我有这个。此时,用户首选项会覆盖URL参数,但如果用户选择es语言并导航到myapp.com/en,则内容将以西班牙语显示。如果用户已登录,我希望URL没有该参数。

# application_controller.rb
class ApplicationController < ActionController::Base
  include SessionsHelper
  before_action :set_locale

  def default_url_options(options = {})
    {locale: I18n.locale}.merge options
  end

  def set_locale
    I18n.locale = (current_user&.locale) || params[:locale] || I18n.default_locale
  end
end

# users_controller.rb
def change_locale
  user = current_user
  user.locale = params[:locale]
  user.save
  redirect_to request.referer
end

# routes.rb

post 'international/:locale' => 'users#change_locale', as: 'international'
scope "(:locale)", locale: /en|es/ do
  # All my routes
end
get '/:locale' => 'static_pages#home' # Fix the home route

# _footer.html.erb
...
<li>
  <%= link_to t('spanish'), international_path(locale: :es), :method => :post %>
</li>
<li>
  <%= link_to t('english'), international_path(locale: :en), :method => :post %>
</li>
...

I18n.available_locales output

[:en, :"da-DK", :"en-GB", :he, :"en-NZ", :"en-au-ocker", :uk, :"en-CA", :ja, :"en-BORK", :"zh-CN", :ru, :de, :"en-AU", :"de-AT", :pl, :"ca-CAT", :fr, :"fi-FI", :vi, :"en-UG", :nl, :"en-SG", :nep, :pt, :ko, :es, :sv, :ca, :"de-CH", :"zh-TW", :sk, :"en-IND", :it, :"en-US", :"pt-BR", :fa, :"nb-NO"]

我的视图代码看起来像这样(现在只有两个链接)

<li>
  <%= link_to "Español", international_path(locale: :es), :metho    d => :post %>
</li>
<li>
  <%= link_to "English", international_path(locale: :en), :method     => :post %>
</li>

PryRpl调试: 当我登录时:如果我手动编写URL,它总是转到用户存储的语言,尽管我写的是哪个URL。它始终显示用户首选项(:en:es) 当我登录并单击显式视图区域设置链接(上述之一)时:用户首选项已更改,因此它将存储的新语言加载到用户首选项。 当我没有登录时:它使用URL参数。

2 个答案:

答案 0 :(得分:0)

感谢同事找到解决方案。

def set_locale
  # Change current_user&.locale to enable ruby <2.3 compatibility
  I18n.locale = (current_user.locale if current_user) || params[:locale] || I18n.default_locale
  redirect_to locale: I18n.locale if request.get? && params[:locale] != I18n.locale.to_s
end

如果有人知道更好的解决方案,请用它发表答案。

答案 1 :(得分:0)

 def set_locale
   if user_signed_in?
   I18n.locale = current_user.language
 else
   I18n.locale = params[:lang] || locale_from_header || I18n.default_locale
  end
end

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