This gem extend the standard i18n backend (I18n::Backend::Simple) to introduce Conventions over configuration about 2 new types of locale files.


1 ) *_formal.yml

Given you want to offer your users the option to be addressed formally or informally through a session locale switch:

Then this is a DRY solution for the workaround about having duplication of de locales in the de_formal namespace even though informal & formal translation are the same.

This locale file will own all translations from its base *.yml and lets you override them through the same translation keys (except of the deviant locale namespaces de and de_formal at the beginning).

2 ) #locales_path/tenants/your_tenant_name/**/your_tenant_name.yml

Given you want to have tenant specific locales through a session locale switch:

Precondition: Assure that you recursively add locale files to i18n's locale path e.g. through your Rails 3 application.rb:

config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]

You may like to enable multi tenancy for your rails application by deploying the repository branch on multiple servers each with a different tenant-specific application constants file to load by a config system like rails_config at initialization.

This locale file owns all translations from its base *.yml and optional *_formal.yml under #locales_path/tenants/your-tenant-name/ (recurively) and lets you override them through the same translation keys (except of the deviant locale namespaces de and de_formal at the beginning).


Add this to your Gemfile and run the bundle command.

gem "multi_formal_i18n_tenancy"

The gem (= engine) will automatically set the backend for your Rails application.

OPTIONAL: you have to manually set the i18n backend for your non-rails Ruby application:

I18n.backend =

Backend Locale Switch

Available since version 0.0.3.


To initialize the global default locale based on current configuration.

Put this file for instance under config/initializer/multi_tenancy.rb

I18n.locale = I18n.backend.available_locale(
  formal: Settings.address_formally, tenant:

Settings is a constant for your settings brought by most popular rack app config system:

I18n.locale = I18n.backend.available_locale(formal: Settings.formal, tenant:



class ApplicationController

  before_filter :set_locale


  def set_locale
    if user_signed_in? 
      # use of devise helper methods: user_signed_in?, current_user
      I18n.locale = current_user.language # you have to add a language string column to your schema
      locale = request.preferred_language_from AVAILABLE_LOCALES
      locale ||= request.compatible_language_from AVAILABLE_LOCALES
      locale ||= I18n.default_locale

      unless == 'global'
        locale = ("#{'-', '_')}_#{locale}").to_sym

    I18n.locale = I18n.backend.available_locale(
      base_locale: locale, formal: Settings.formal_address, tenant:


Tested on MacOS with: Rails 3.1 & Ruby 1.9.2, Rails 3.2.6 & Ruby 1.9.3.


  • Support of more backends than only standard simple one


Just follow the screencast of Ryan Bates on

Add a description about your changes to under section multi_formal_i18n_tenancy (unreleased).


This project uses MIT-LICENSE.