Development/Production parity for Rails Internationalization
To support both English and Spanish in web apps, we can use Ruby’s
library, which allows for easy translations through YAML files for each
language. If a translation is missing, ideally we’d like to see an error in our
tests, which makes the test suite fail. However, if our development environment
is not set up to raise exceptions, there could be bugs lurking, or waiting to
One such instance happened to us recently, because our
that’s a thing!) in Rails was different in the development/testing and
production environments. Development used the “base” i18n backend, while
production was set up to use the “fallbacks” backend.
This difference made it so that production showed this output when rendering a PDF:
1 2 2.5.1 :001 > helper.render inline: "<%= t(nil, scope: 'contact_relationship_mappings') %>" => "<span class=\"translation_missing\" title=\"translation missing: en.contact_relationship_mappings\">Contact Relationship Mappings</span>"
While development/testing showed this:
1 2 2.5.1 :001 > helper.render inline: "<%= t(nil, scope: 'contact_relationship_mappings') %>" => ""
Two very different outputs, produced by the difference in the i18n backends. The first one falls back to whatever string the scope was, and the second one returns an empty string. By using the same backend, we can more easily detect failures and have it behave the same way across environments.
Factor #10 in the twelve-factor app methodology is keeping development and production as similar as possible, which is what I tried to exemplify in this article.
The twelve-factor developer resists the urge to use different backing services between development and production, …
The same applies to other parts of our tech stack. The more things we have in common between development and production, the more things we can expect to go right or wrong earlier. And when things do go wrong, we have a better debugging environment set up.