简体   繁体   中英

How to turn a translations table into YAML translation files in ruby on rails

My app is currently using the gem i18n-active_record for translations, storing them in a table translations which has more than 5000 records.

To improve performance, I want to move the translations to YAML files, eg en.yml and ar.yml .

I tried File.open(Rails.root+'config/locales/en.yml', 'w') {|f| f.write translation.to_yaml } File.open(Rails.root+'config/locales/en.yml', 'w') {|f| f.write translation.to_yaml } but the output generated is the following:

    raw_attributes:
    id: 1
    locale: en
    key: footer.new_car_make
    value: New %{title} Cars
    interpolations: 
    is_proc: 0
    created_at: &4 2012-08-15 06:25:59.000000000 Z
    updated_at: &5 2012-08-15 06:25:59.000000000 Z

Is there any easy way to make the conversion?

You can try something like this (I don't have any DB backed Rails Translations to try this)

def assign(parts, value, data)
  key, *rest = parts
  if rest.empty?
    data[key] = value
  else
    data[key] ||= {}
    assign(rest, value, data[key])
  end
end

translations = {}
Translation.all.each do |translation|
  path = [translation.locale] + translation.key.split(".")
  assign(path, translation.value, translations)
end

File.write("translations.yml", translations.to_yaml)

Of course you can modify to only export the translations of a single locale or specific keys (by changing the all to a where query).

The code works as following:

It iterates all the Translations, and builds a hash with all the translations. The key footer.new_car_make of the en translation will end up in a nested hash like:

{
  "en" => {
    "footer" => {
      "new_car_make" => "Whatever text you have in the DB"
    }
  }
}

and then this hash is saved as YAML format in a file.

The assign method is called with the full key (it contains the locale as well) represented as an array ( ['en', 'footer', 'new_car_make'] ) and deconstructs into a head (first value in the array) and the rest (remaining parts). If the remaining part is empty, it means we've reached the last element and can assign the value, otherwise we add a nested hash and recurse.

You can try this in the console (just copy paste it). As mentioned this might not run right out of the box, let me know if you have troubles.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM