TML for Rails & Globalize Gem

Suppose we have a Rails application with a large data set that we need to translate to a few languages. It is important that we store the data in our own database to preserve its integrity and provide internal searching capabilities. So how can we do this without having to invest too much time into building our own translation management platform?

Let’s use a simple Famous Quotes application as an example. This application contains 36,000 famous quotes that we would like to translate to a few languages. Our goal is to store all the quotes and their translations in our database and use crowdsourcing approach – asking users to help us translate the quotes or vote on existing translations. We will use Translation Exchange as a platform that will handle most of the work for us. All we have to do is handle the translation storage.

Using Globalize Gem

We need some kind of mechanism to store the translations in our database. Globalize gem is one of the best solutions for storing translations in Rails apps.

You can install the gem using the following url:

For instructions on how to set it up, visit this url:

In short, simply add the gem to your Gemfile:

and run:

Configuring Our Application

In our application, all of the quotes data is stored in a single table, called “quotes”:


Name Type
id int
quote text
author string
authordata string

And we have a Quote model that loads and stores data in the database:

To make the quote data globalizable, we add the following definition to our code:

We then add a migration for generating the supporting localization tables that would store our translations:

And run the migrations:

This will generate the following supporting translations table:


Name Type
id int
quote_id int
locale string
quote text
author string
authordata string

To access the Quote data in other languages, we simply do:

Similarly, to store the data in other locales, we use:

Synchronizing Data with Translation Exchange

So now that we have a mechanism for storing and retrieving quotes data, let’s integrate our app with Translation Exchange and use its Translation Center and machine translations for getting the actual translations.

Besides translating the data, we may want to translate the chrome of the application (the static labels, buttons, links). We will use TML for Rails to do both chrome translation and data translation. So let’s first add the TML gem to our app.

Simply add the gem to your Gemfile:

and run:

Create a new initializer file with the following content:

To learn more about all the available options of TML, visit:

You can follow the above guide to see how to translate the chrome of your application. In this post, we will focus on how to synchronize the data with Translation Exchange. To do so, let’s create a new rake task with the following code:

Now we can run the following rake task to sync up all the translation keys using:

And import translations using:

The following sections will provide more details on the methods used in the rake tasks above.

Registering Translation Keys

This method allows you to register the content of your application with Translation Exchange.



Name Type Description
source_keys array Translation source/key objects
options hash Additional options: realtime (true/false)


The source keys must be an array of the following objects:

SOURCE_OBJECT contains the human readable source name and a source id to identify the source during import. For instance, in the above quotes application, we used:

KEY_OBJECT contains translation key information, such as original label, locale and a system id.

Sources allow us to group many keys together so it would be easier to organize and retrieve them later. In our examples, we wanted to create a source object for every quote, where quote’s text, author and authorinfo were all translation keys under the quote.


If you don’t need to store the translation key reference data in your database, then you should always set the realtime option to false. This will significantly speed up the key export. If you do set the realtime to true, you will get the following information back:

If you store the reference key data, then you can access our public api to get individual keys translations:


A much faster and better approach is to synchronize/extract translations in bulk using the following method.

Syncing Translations

This method allows you to extract translations from Translation Exchange from your project’s translation memory.



Name Type Description
since date/time Format: 2015-12-01 10:30. Start date from which to get translations.
until date/time Format: 2015-12-01 10:30. End date until which to get translations.
locales array Comma separated list of locales. Only pull translations for the specified locales.
source string Only pulls translations that belong to translation keys matching a specific source key.
translators array Comma separated list of translator ids. Only pulls translations submitted by the specified translators.
imported boolean Format: true/false. Only pulls translations for imported translation keys.Keys that have been imported from files.
machine boolean Format: true/false. Only pulls translations that have been machine translated.
locked boolean Format: true/false. Only pulls translations that have been locked either by a reviewer or through purchasing from a 3rd party vendor.
purchases boolean Format: true/false. Only pulls translations that have been purchased from a 3rd party vendor.

The data from this call is returned in the following format:

Where TRANSLATION_OBJECT provides information about the original translation key and translation:

Here is a full example of the data set:

Notice that it is possible to have the same translation key be part of many sources, that’s why the “sources” attribute is an array of sources. It is completely up to you how you structure the sources – as long as you have a way to identify the data in your system and store the translations associations.

To view the source code for the above quotes application, please visit:

If you have any questions about the above scripts, please contact our support: