From bcccf8b6a23d66f78d8b1349f92dcc19373daa9d Mon Sep 17 00:00:00 2001 From: Gannon McGibbon Date: Mon, 29 Oct 2018 15:58:29 -0400 Subject: [PATCH] Make i18n locale setting docs use around_action Changes `I18n.locale` assignment in docs to use `I18n.with_locale` in `around_action` to ensure locale resetting after action processing. [ci skip] [Gannon McGibbon + Leonardo Tegon] --- guides/source/i18n.md | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/guides/source/i18n.md b/guides/source/i18n.md index c61b6ad214..10b1a6de7e 100644 --- a/guides/source/i18n.md +++ b/guides/source/i18n.md @@ -143,13 +143,14 @@ The default locale is used for all translations unless `I18n.locale` is explicit A localized application will likely need to provide support for multiple locales. To accomplish this, the locale should be set at the beginning of each request so that all strings are translated using the desired locale during the lifetime of that request. -The locale can be set in a `before_action` in the `ApplicationController`: +The locale can be set in an `around_action` in the `ApplicationController`: ```ruby -before_action :set_locale +around_action :switch_locale -def set_locale - I18n.locale = params[:locale] || I18n.default_locale +def switch_locale(&action) + locale = params[:locale] || I18n.default_locale + I18n.with_locale(locale, &action) end ``` @@ -169,10 +170,11 @@ One option you have is to set the locale from the domain name where your applica You can implement it like this in your `ApplicationController`: ```ruby -before_action :set_locale +around_action :switch_locale -def set_locale - I18n.locale = extract_locale_from_tld || I18n.default_locale +def switch_locale(&action) + locale = extract_locale_from_tld || I18n.default_locale + I18n.with_locale(locale, &action) end # Get locale from top-level domain or return +nil+ if such locale is not available @@ -212,7 +214,7 @@ This solution has aforementioned advantages, however, you may not be able or may #### Setting the Locale from URL Params -The most usual way of setting (and passing) the locale would be to include it in URL params, as we did in the `I18n.locale = params[:locale]` _before_action_ in the first example. We would like to have URLs like `www.example.com/books?locale=ja` or `www.example.com/ja/books` in this case. +The most usual way of setting (and passing) the locale would be to include it in URL params, as we did in the `I18n.with_locale(params[:locale], &action)` _around_action_ in the first example. We would like to have URLs like `www.example.com/books?locale=ja` or `www.example.com/ja/books` in this case. This approach has almost the same set of advantages as setting the locale from the domain name: namely that it's RESTful and in accord with the rest of the World Wide Web. It does require a little bit more work to implement, though. @@ -275,8 +277,11 @@ NOTE: Have a look at various gems which simplify working with routes: [routing_f An application with authenticated users may allow users to set a locale preference through the application's interface. With this approach, a user's selected locale preference is persisted in the database and used to set the locale for authenticated requests by that user. ```ruby -def set_locale - I18n.locale = current_user.try(:locale) || I18n.default_locale +around_action :switch_locale + +def switch_locale(&action) + locale = current_user.try(:locale) || I18n.default_locale + I18n.with_locale(locale, &action) end ``` @@ -291,10 +296,11 @@ The `Accept-Language` HTTP header indicates the preferred language for request's A trivial implementation of using an `Accept-Language` header would be: ```ruby -def set_locale +def switch_locale(&action) logger.debug "* Accept-Language: #{request.env['HTTP_ACCEPT_LANGUAGE']}" - I18n.locale = extract_locale_from_accept_language_header + locale = extract_locale_from_accept_language_header logger.debug "* Locale set to '#{I18n.locale}'" + I18n.with_locale(locale, &action) end private @@ -335,10 +341,12 @@ end ```ruby # app/controllers/application_controller.rb class ApplicationController < ActionController::Base - before_action :set_locale - def set_locale - I18n.locale = params[:locale] || I18n.default_locale + around_action :switch_locale + + def switch_locale(&action) + locale = params[:locale] || I18n.default_locale + I18n.with_locale(locale, &action) end end ```