Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix memoization, bring back Implementation Module #129

Merged
merged 4 commits into from
Dec 1, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 79 additions & 75 deletions lib/i18n/backend/active_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ class ActiveRecord
autoload :Translation, 'i18n/backend/active_record/translation'
autoload :Configuration, 'i18n/backend/active_record/configuration'

include Base
include Flatten

class << self
def configure
yield(config) if block_given?
Expand All @@ -30,103 +27,110 @@ def initialize(*args)
reload!
end

def available_locales
Translation.available_locales
rescue ::ActiveRecord::StatementInvalid
[]
end
module Implementation
include Base
include Flatten

def store_translations(locale, data, options = {})
escape = options.fetch(:escape, true)
def available_locales
Translation.available_locales
rescue ::ActiveRecord::StatementInvalid
[]
end

flatten_translations(locale, data, escape, false).each do |key, value|
translation = Translation.locale(locale).lookup(expand_keys(key))
def store_translations(locale, data, options = {})
escape = options.fetch(:escape, true)

if self.class.config.cleanup_with_destroy
translation.destroy_all
else
translation.delete_all
flatten_translations(locale, data, escape, false).each do |key, value|
translation = Translation.locale(locale).lookup(expand_keys(key))

if self.class.config.cleanup_with_destroy
translation.destroy_all
else
translation.delete_all
end

Translation.create(locale: locale.to_s, key: key.to_s, value: value)
end

Translation.create(locale: locale.to_s, key: key.to_s, value: value)
reload! if self.class.config.cache_translations
end

reload! if self.class.config.cache_translations
end

def reload!
@translations = nil
def reload!
@translations = nil

self
end
self
end

def initialized?
!@translations.nil?
end
def initialized?
!@translations.nil?
end

def init_translations
@translations = Translation.to_hash
end
def init_translations
@translations = Translation.to_hash
end

def translations(do_init: false)
init_translations if do_init || !initialized?
@translations ||= {}
end
def translations(do_init: false)
init_translations if do_init || !initialized?
@translations ||= {}
end

protected
protected

def lookup(locale, key, scope = [], options = {})
key = normalize_flat_keys(locale, key, scope, options[:separator])
key = key[1..-1] if key.first == '.'
key = key[0..-2] if key.last == '.'
def lookup(locale, key, scope = [], options = {})
key = normalize_flat_keys(locale, key, scope, options[:separator])
key = key[1..-1] if key.first == '.'
key = key[0..-2] if key.last == '.'

if self.class.config.cache_translations
keys = ([locale] + key.split(I18n::Backend::Flatten::FLATTEN_SEPARATOR)).map(&:to_sym)
if self.class.config.cache_translations
keys = ([locale] + key.split(I18n::Backend::Flatten::FLATTEN_SEPARATOR)).map(&:to_sym)

return translations.dig(*keys)
end
return translations.dig(*keys)
end

result = if key == ''
Translation.locale(locale).all
else
Translation.locale(locale).lookup(key)
end
result = if key == ''
Translation.locale(locale).all
else
Translation.locale(locale).lookup(key)
end

if result.empty?
nil
elsif result.first.key == key
result.first.value
else
result = result.inject({}) do |hash, translation|
hash.deep_merge build_translation_hash_by_key(key, translation)
if result.empty?
nil
elsif result.first.key == key
result.first.value
else
result = result.inject({}) do |hash, translation|
hash.deep_merge build_translation_hash_by_key(key, translation)
end
result.deep_symbolize_keys
end
result.deep_symbolize_keys
end
end

def build_translation_hash_by_key(lookup_key, translation)
hash = {}
def build_translation_hash_by_key(lookup_key, translation)
hash = {}

chop_range = if lookup_key == ''
0..-1
else
(lookup_key.size + FLATTEN_SEPARATOR.size)..-1
end
translation_nested_keys = translation.key.slice(chop_range).split(FLATTEN_SEPARATOR)
translation_nested_keys.each.with_index.inject(hash) do |iterator, (key, index)|
iterator[key] = translation_nested_keys[index + 1] ? {} : translation.value
iterator[key]
end
chop_range = if lookup_key == ''
0..-1
else
(lookup_key.size + FLATTEN_SEPARATOR.size)..-1
end
translation_nested_keys = translation.key.slice(chop_range).split(FLATTEN_SEPARATOR)
translation_nested_keys.each.with_index.inject(hash) do |iterator, (key, index)|
iterator[key] = translation_nested_keys[index + 1] ? {} : translation.value
iterator[key]
end

hash
end
hash
end

# For a key :'foo.bar.baz' return ['foo', 'foo.bar', 'foo.bar.baz']
def expand_keys(key)
key.to_s.split(FLATTEN_SEPARATOR).inject([]) do |keys, k|
keys << [keys.last, k].compact.join(FLATTEN_SEPARATOR)
# For a key :'foo.bar.baz' return ['foo', 'foo.bar', 'foo.bar.baz']
def expand_keys(key)
key.to_s.split(FLATTEN_SEPARATOR).inject([]) do |keys, k|
keys << [keys.last, k].compact.join(FLATTEN_SEPARATOR)
end
end
end

include Implementation
end
end
end