Rails is not persistent

I am trying to develop a bilingual application.

However, I found that changing the locale is not constant by default for i18n.

I have this index page and provided a link to change the default language.

<% if I18n.locale == I18n.default_locale %> <%= link_to "English", :locale=>'en'%> <% else %> <%= link_to "Franรงais", :locale=>'fr'%> <%end%> 

The problem is that when you enter another page, the language standard returns to the default language.

So, Iโ€™m just wondering how to save the user's language selection and constantly use this language until the user logs out.

Thanks in advance.

+5
source share
3 answers

I recommend that you read the Rails guides about I18n to understand how I18n works in Rails. Obviously, the I18n.locale change is temporary and will be reset per session.

According to your requirement, you can save the selected language in session . Here is a sample code:

 # app/controllers/application_controller.rb class ApplicationController < ActionController::Base before_action :set_locale def set_locale I18n.locale = params[:locale] || session[:locale] || I18n.default_locale session[:locale] = I18n.locale end end 

You can then clear session[:locale] when the user logs out.

 # app/controllers/sessions_controller.rb class SessionsController < ApplicationController def sign_out # ... session.delete :locale end end 
+3
source

If you look at the docs , he says

You may be tempted to save the selected locale in a session or in a cookie, but do not. The locale must be transparent and part of the URL. Thus, you do not violate the basic assumptions about the website itself: if you send the URL to a friend, they should see the same page and content as you.

If you installed your locals in a domain name or URL, it has several advantages

 1. The locale is an obvious part of the URL. 2. People intuitively grasp in which language the content will be displayed. 3. It is very trivial to implement in Rails. 4. Search engines seem to like that content in different languages lives at different, inter-linked domains. 

Fix

a. You can pass locals in the urls and then set the filter:

In this case, your URL will look like www.example.com/books?locale=ja or www.example.com/ja/books , and then in the application controller you can set your local filter

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

To include an explicit parameter in every URL (e.g. link_to (books_url (locale: I18n.locale))) would be tedious and possibly impossible, so you can redefine the default_url_options rails somehow like this in a controller application

 # app/controllers/application_controller.rb def default_url_options(options={}) logger.debug "default_url_options is passed options: #{options.inspect}\n" { locale: I18n.locale } end 

This will allow every helper method dependent on url_for (for example, helpers for named routes such as root_path or root_url, resource routes such as books_path or books_url, etc.) will now automatically include the locale in the query string, for example: http: //www.example.com/?locale=ja .

but if you prefer to use your URLs to look like www.example.com/en/books , for this you need to override the default_url_options method, and you will also need to combine your routes as follows:

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

b. Setting the locale from client information:

People can install Accept-Language in their browser or other clients (e.g. curl), and you can use it like this in an application controller:

 def set_locale logger.debug "* Accept-Language: #{request.env['HTTP_ACCEPT_LANGUAGE']}" I18n.locale = extract_locale_from_accept_language_header logger.debug "* Locale set to '#{I18n.locale}'" end private def extract_locale_from_accept_language_header request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[az]{2}/).first end 
+4
source

Itโ€™s good practice to set the language and add this locale to default_url_options a in the ApplicationController :

 before_filter :set_locale def set_locale I18n.locale = params[:locale] || I18n.default_locale end def default_url_options(options={}) { locale: I18n.locale } end 

Then add the scope of route.rb :

 scope "/:locale", locale: /en|fr/ do your routes goes here end 

And in layouts / application.html.erb :

  <%= link_to "English", { locale: :en }%> <%= link_to "French", { locale: :fr } %> 

A good day.

+1
source

Source: https://habr.com/ru/post/1200430/


All Articles