lib/enum_ish/dictionary.rb in enum_ish-1.4.1 vs lib/enum_ish/dictionary.rb in enum_ish-1.5.0

- old
+ new

@@ -1,12 +1,16 @@ +# frozen_string_literal: true + module EnumIsh class Dictionary + CACHE_KEY = :_enum_ish_dictionary_cache + def initialize(klass, enum, options = {}) @klass = klass @enum = enum @options = options - @dict = load_dict + @dict = cache { Lookup.new(@klass, @enum, @options).call } end def translate_value(value) if value.is_a?(Array) value.map { |v| @dict[v] || v } @@ -19,43 +23,63 @@ @dict.to_a.map { |value, label| [label, value] } end private - def load_dict - i18n = load_from_i18n.transform_keys { |k| k.to_s.to_sym } + def cache + if (cache = Thread.current[CACHE_KEY]) != nil + cache[I18n.locale] ||= {} + cache[I18n.locale][@klass] ||= {} + cache[I18n.locale][@klass][@enum] ||= {} + cache[I18n.locale][@klass][@enum][@optons] ||= yield + else + yield + end + end + class << self + def cache + Thread.current[CACHE_KEY] = {} + yield + ensure + Thread.current[CACHE_KEY] = nil + end + end + end + + class Lookup + def initialize(klass, enum, options = {}) + @klass = klass + @enum = enum + @options = options + end + + def call + i18n = lookup_for(@klass).transform_keys { |k| k.to_s.to_sym } + dict = {} if @enum.setting[:accessor] @enum.mapping.each { |k, v| dict[k] = i18n[k].to_s } else @enum.mapping.each { |k, v| dict[v] = i18n[k].to_s } end filter(dict) end - def load_from_i18n + private + + def lookup_for(klass) key = [@enum.name, @options[:format]].compact.join('/') options = (@options[:i18n_options] || {}).merge(default: nil) - dict = I18n.t(:"enum_ish.#{@klass.name.underscore}.#{key}", **options) - return dict if dict - i18n_ancestors.each do |ancestor| - dict = I18n.t(:"enum_ish.#{ancestor.name.underscore}.#{key}", **options) - return dict if dict + if klass.name.to_s.in?(['ActiveRecord::Base', 'Object']) + I18n.t(:"enum_ish.defaults.#{key}", **options) || @enum.mapping.invert + elsif klass.name.blank? || !klass.is_a?(Class) + resolve(klass.superclass) + else + I18n.t(:"enum_ish.#{klass.name.underscore}.#{key}", **options) || lookup_for(klass.superclass) end - - dict = I18n.t(:"enum_ish.defaults.#{key}", **options) - return dict if dict - - @enum.mapping.invert - end - - def i18n_ancestors - @klass.ancestors.drop(1) - .take_while { |a| a.name != 'ActiveRecord::Base' && a.name != 'Object' } - .select { |a| a.is_a?(Class) && !a.name.empty? } end def filter(dict) if @options[:except] except = Array(@options[:except])