class I18nTranslationGenerator

Public Instance Methods

main() click to toggle source

option: include_timestamps

# File lib/generators/i18n_translation/i18n_translation_generator.rb, line 6
def main
  unless file_name =~ /^[a-zA-Z]{2}([-_][a-zA-Z]+)?$/
    log 'ERROR: Wrong locale format. Please input in ?? or ??-?? format.'
    exit
  end
  log "translating models to #{locale_name}..."
  I18n.locale = locale_name
  if Rails.try(:autoloaders).try(:zeitwerk_enabled?)
    Zeitwerk::Loader.eager_load_all
  else
    Rails.application.eager_load!
  end

  # activerecord:models comes first
  model_names_translations = order_hash translate_all(model_names_keys)
  # activerecord:models:attributes comes next
  attribute_names_translations = ActiveSupport::OrderedHash.new
  attribute_names_translations.merge! translate_all(content_column_names_keys)
  attribute_names_translations.merge! translate_all(collection_reflection_names_keys)
  # refer to already translated model names
  attribute_names_translations.merge! singular_reflection_names_references
  # merge them all
  translations = model_names_translations.deep_merge order_hash(attribute_names_translations)

  yaml = I27r::YamlDocument.load_yml_file "config/locales/translation_#{locale_name}.yml"
  each_value [], translations do |parents, value|
    if value.is_a?(String) || value.is_a?(Symbol)
      yaml[[locale_name.to_s] + parents] = value
    else
      value.each do |key, val|
        yaml[[locale_name.to_s] + parents + [key.to_s]] = val
      end
    end
  end

  unless (yaml_string = yaml.to_s(true)).blank?
    create_file "config/locales/translation_#{locale_name}.yml", yaml_string
  end
end

Private Instance Methods

collection_reflection_names_keys() click to toggle source
# File lib/generators/i18n_translation/i18n_translation_generator.rb, line 82
def collection_reflection_names_keys
  models.map {|m|
    m.reflect_on_all_associations.select {|c| c.collection?}.map {|c| "activerecord.attributes.#{m.model_name.to_s.underscore}.#{c.name}"}
  }.flatten
end
content_column_names_keys() click to toggle source
# File lib/generators/i18n_translation/i18n_translation_generator.rb, line 64
def content_column_names_keys
  models.map {|m|
    cols = m.content_columns.map {|c| c.name}
    cols.delete_if {|c| %w[created_at updated_at].include? c} unless include_timestamps?
    cols.map {|c| "activerecord.attributes.#{m.model_name.to_s.underscore}.#{c}"}
  }.flatten
end
each_value(parents, src) { |parents| ... } click to toggle source

iterate through all values

# File lib/generators/i18n_translation/i18n_translation_generator.rb, line 131
def each_value(parents, src, &block)
  src.each do |k, v|
    if v.is_a?(ActiveSupport::OrderedHash)
      each_value parents + [k], v, &block
    else
      yield parents + [k], v
    end
  end
end
include_timestamps?() click to toggle source
# File lib/generators/i18n_translation/i18n_translation_generator.rb, line 112
def include_timestamps?
  !!@include_timestamps
end
locale_name() click to toggle source
# File lib/generators/i18n_translation/i18n_translation_generator.rb, line 108
def locale_name
  @_locale_name ||= file_name.tr('_', '-').split('-').each.with_index.map {|s, i| i == 0 ? s : s.upcase}.join('-')
end
model_names_keys() click to toggle source
# File lib/generators/i18n_translation/i18n_translation_generator.rb, line 60
def model_names_keys
  models.map {|m| "activerecord.models.#{m.model_name.to_s.underscore}"}
end
models() click to toggle source
# File lib/generators/i18n_translation/i18n_translation_generator.rb, line 47
def models
  ar_descendants = ActiveRecord::Base.descendants
  ar_descendants.delete(ActiveRecord::SchemaMigration) if defined?(ActiveRecord::SchemaMigration)
  @models ||= ar_descendants.map do |m|
    begin
      m if m.table_exists? && m.respond_to?(:content_columns)
    rescue => e
      p e
      next
    end
  end.compact
end
order_hash(hash) click to toggle source

transform a Hash into a nested OrderedHash

# File lib/generators/i18n_translation/i18n_translation_generator.rb, line 117
def order_hash(hash)
  ActiveSupport::OrderedHash.new.tap do |oh|
    hash.sort_by {|k, _v| k}.each do |key, value|
      if key.to_s.include? '.'
        key_prefix, key_suffix = key.to_s.split('.')[0...-1], key.to_s.split('.')[-1]
        key_prefix.inject(oh) {|h, k| h[k] ||= ActiveSupport::OrderedHash.new}[key_suffix] = value
      else
        oh[key] = value
      end
    end
  end
end
singular_reflection_names_references() click to toggle source
# File lib/generators/i18n_translation/i18n_translation_generator.rb, line 72
def singular_reflection_names_references
  ret = {}
  models.each do |m|
    m.reflect_on_all_associations.select {|c| !c.collection?}.each do |c|
      ret["activerecord.attributes.#{m.model_name.to_s.underscore}.#{c.name}"] = "activerecord.models.#{c.name}".to_sym
    end
  end
  ret
end
translate_all(keys) click to toggle source

receives an array of keys and returns :key => :translation hash

# File lib/generators/i18n_translation/i18n_translation_generator.rb, line 93
def translate_all(keys)
  ret, threads = {}, []
  keys.each do |key|
    threads << Thread.new do
      Rails.logger.debug "translating #{key} ..."
      Thread.pass
      key_prefix, key_suffix = key.to_s.split('.')[0...-1], key.to_s.split('.')[-1]
      existing_translation = I18n.backend.send(:lookup, locale_name, key_suffix, key_prefix)
      ret[key] = existing_translation ? existing_translation : translator.translate(key_suffix)
    end
  end
  threads.each {|t| t.join}
  ret
end
translator() click to toggle source
# File lib/generators/i18n_translation/i18n_translation_generator.rb, line 88
def translator
  @translator ||= I27r::Translator.new locale_name.sub(/\-.*/, '')
end