Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Some conventions / guidelines / best practices that helped me while working on internationalization of a rails app

Internationalization of a Rails App : conventions / guidelines / best practices

I have worked, and am currently working on internationalization of a Rails app. The apps require translating the ActiveRecord models. I have done some googling, but haven't really found any best practices / conventions / guidelines on how to think through this and what guidelines to follow.

I decided to create this document, to give myself a start and have it possibly help others. I am not an expert at any of this, and there may be things I am thinking incorrectly, but having it documented makes it easier to see the flaws and improve upon. If you have some ideas on additions, or think that somethings should change, get in touch.

Note: I use Globalize for model translations

  • I18n.locale controls the app wide locale. It refers to the particular localization version of the app. It defines how the app is localized to the user. It's scope is somewhat larger than the language/translation of the content in consideration. So use that parameter when the app needs to be localized to a user, not just to refer to the translation of the resource.

  • When using Globalize, Globalize.locale controls the translation (or locale) of ActiveRecord models. It does not have to match with I18n.locale. When they both don't match, ActiveRecord returns the translation corresponding to Globalize.locale (unless one doesn't exist).

  • Use the translation, language or lang query parameter parameter (in the context of resource / model translations) to describe the translation language of the resource the user has requested. For the use case in which, for a particular locale, the user requests a translation of a resource that is different from the default translation, use the translation/language/lang locale for it.

  • It is fair to have the language / lang parameter default to locale unless the user wants language to be different from the locale.

  • Set both I18n.locale and Globalize locale on every request. This currently works as a workaround for a bug, and might not be a bad practice anyway.

  • Set Globalize.locale to I18n.locale just after I18n.locale is set. It can be changed later based on the use-case to deliver the correct model translation.

  • To create a translation use ActiveRecord#update_attributes like so: @tranlsated_object.update_attributes(:title => 'Title', :locale => :ko)

  • Do not set up a AR class around the Globalize translations table unless you are really sure you cannot do without it, for the following reasons:

    • This avoids temptation to write hacky code in the translations class, once that is defined, and write complex code.
    • This will force you to use Globalize3 API correctly.
    • This will also force us to contributing to Globlize3 API, which is something we should be eager to do since it will help for us to have a better codebase.
  • When testing, set up a default RSpec hook to reset locale after every test. When writing every test, write it with keeping in mind that all locales are set to defaults. It might be benificial to reset locale after every test rather than before.

    RSpec.configure do |config|
      config.after(:each) do 
        I18n.locale = :en
        Globalize.locale = :en
  • When you work on your rails app, you will probably use default_url_options to use I18n.locale as the default locale parameter for your route / path helpers. However this doesn't work in tests. I picked up a solution from this github issue on rspec-rails. I monkey patch ActionDispatch::Routing::RouteSet like so:

    class ActionDispatch::Routing::RouteSet
      def url_for_with_locale_fix(options={})
        url_for_without_locale_fix(options.merge(:locale => I18n.locale))
      alias_method_chain :url_for, :locale_fix
  • Set up a translate helper 't' as a wrapper around the I18n.t method

    module I18nHelper
      def t string, options = {}
        I18n.t string, options
    RSpec.configure do |config|
      config.include I18nHelper

This comment has been minimized.

Copy link

@halilim halilim commented Oct 10, 2015

Another hack for the last item (using t() in tests):

RSpec.configure do |config|
  config.include AbstractController::Translation # I18n.t -> t

(You might need to read the documentation of AbstractController::Translation#translate for some edge cases.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment