By default Rails uses YAML files to store internationalization information. But we are not restricted to use YAML (that is only capable of reading translations but cannot dynamically store them). We can use any database as backend.
To start, you can use this gem: https://github.com/svenfuchs/i18n-active_record
You can change the default backend like that:
I18n.backend = Globalize::Backend::Static.new
You can also use Chan backend to chain multiple backends together.
# config/initializers/locale.rb
I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend)
But, As the translations are accessed frequently in every request page, ActiveRecord is not the best approach. For these reason, a key-value store is the way to go.
You can use Redis database for this:
First install Redis
$ brew install redis
Install redis gem:
# Gemfile
source 'http://rubygems.org'
# ...
gem 'redis'
Now you can change the backend like that:
# config/initializers/locale.rb
I18n.backend = I18n::Backend::KeyValue.new(Redis.new)
Code to add translation:
# /app/views/admin/translations/index.html.erb
<%= form_tag admin_translations_path do %>
<p>
<%= label_tag :locale %><br>
<%= text_field_tag :locale %>
</p>
<p>
<%= label_tag :key %><br>
<%= text_field_tag :key %>
</p>
<p>
<%= label_tag :value %><br>
<%= text_field_tag :value %>
</p>
<p><%= submit_tag "Submit" %></p>
<% end %>
This form will POST to admin/TranslationsController's create action:
# /app/controllers/admin/translations_controller.rb
module Admin
class TranslationsController < ApplicationController
# ....
def create
I18n.backend.store_translations(params[:locale]), {params[:key] => params[:value]}, escape: false)
redirect_to admin_translations_path, notice: "Translation Added"
end
end
end
You can also use redis-i18n
gem to do the same: https://github.com/redis-store/redis-i18n