Rails i18n

configuration of Rails app to support I18n.


routes

routes.rb:

Rails.application.routes.draw do
  scope '(:locale)', locale: /en/ do
    # all your routes
  end
end

application_controller.rb:

class ApplicationController < ActionController::Base
  before_action :set_locale

  ...

private

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

  def default_url_options options = {}
    options.merge locale: params[:locale]
  end

  ...
end

this scheme doesn’t work with custom URL generator class that includes Rails.application.routes.url_helpers module. URL helpers available from this module won’t have access to view context and consequently to default URL options set in ApplicationController - they will try to use the first argument as a value for locale parameter which will result in no route matches error.

solution: don’t use URL generator classes and pass view context explicitly whenever it’s necessary to use URL helpers outside of controller or view.

active admin

AA controllers are not inherited from ApplicationController and consequently don’t have correct default URL options set.

that is why URL helpers in AA don’t generate correct URLs (for the same reason as URL helpers in custom URL generator classes above).

simple solution is to exclude AA routes from locale scope in routes.rb:

Rails.application.routes.draw do
  scope '(:locale)', locale: /en/ do
    ...
  end

  ActiveAdmin.routes(self)
end

RSpec

WARNING: obsolete section - see rails console for details.

for some obscure reason locale is not set to default locale (config.i18n.default_locale option in application.rb) and defaults to :en.

thusly it has to be set manually (either to :ru or I18n.default_locale):

NOTE: translations from class methods are loaded before before block!

rails console

by default locale is :en (e.g. in rails console and RSpec) even when default locale is set to :ru in application.rb.

to fix it add initializer config/initializers/i18n.rb:

I18n.locale = :ru
I18n.load_path += Dir[Rails.root.join('config/locales/**/*.yml')]
I18n.reload!

adding all yml files from config/locales/ to load path is not obligatory here since all translations from config/locales/*.rb,yml must be auto loaded.

adding this initializer fixes locale for RSpec as well - it’s no longer necessary to explicitly set locale in RSpec config files.

mailers

application.rb:

config.action_mailer.default_url_options = {
  host: Pumba::DOMAIN, only_path: false, locale: I18n.locale
}

Sidekiq

https://github.com/mperham/sidekiq/issues/750

config/initializers/sidekiq.rb:

require 'sidekiq/middleware/i18n'

Capybara

URL helpers used in feature specs don’t use default URL options from ApplicationController for the same reason as URL helpers from custom URL generator class (see above).

one workaround for this problem is to define ad hoc default_url_options method for specs.

spec/support/capybara_support.rb:

module CapybaraSupport
  def default_url_options
    { locale: nil }
  end
end

then include this module in each feature spec that uses URL helpers:

include CapybaraSupport

feature 'sign in' do
  ...
end