3 class AttributeStash < Hash
4 def contains?(locale, attr_name)
7 self[locale].has_key? attr_name
10 def read(locale, attr_name)
11 locale = locale.to_sym
13 self[locale][attr_name]
16 def write(locale, attr_name, value)
17 locale = locale.to_sym
19 self[locale][attr_name] = value
24 def initialize(record)
27 # TODO what exactly are the roles of cache and stash
28 @cache = AttributeStash.new
29 @stash = AttributeStash.new
32 def fetch(locale, attr_name)
33 # locale = I18n.locale
34 is_cached = @cache.contains?(locale, attr_name)
35 is_cached ? @cache.read(locale, attr_name) : begin
36 value = fetch_attribute locale, attr_name
37 @cache.write locale, attr_name, value if value && value.locale == locale
42 def stash(locale, attr_name, value)
43 @stash.write locale, attr_name, value
44 @cache.write locale, attr_name, value
47 def update_translations!
48 @stash.each do |locale, attrs|
49 translation = @record.globalize_translations.find_or_initialize_by_locale(locale.to_s)
50 attrs.each{|attr_name, value| translation[attr_name] = value }
64 def fetch_attribute(locale, attr_name)
65 fallbacks = I18n.fallbacks[locale].map{|tag| tag.to_s}.map(&:to_sym)
67 # If the translations were included with
68 # :include => globalize_translations
69 # there is no need to query them again.
70 unless @record.globalize_translations.loaded?
71 translations = @record.globalize_translations.by_locales(fallbacks)
73 translations = @record.globalize_translations
75 result, requested_locale = nil, locale
77 # Walk through the fallbacks, starting with the current locale itself, and moving
78 # to the next best choice, until we find a match.
79 # Check the @globalize_set_translations cache first to see if we've just changed the
80 # attribute and not saved yet.
81 fallbacks.each do |fallback|
82 # TODO should we be checking stash or just cache?
83 result = @stash.read(fallback, attr_name) || begin
84 translation = translations.detect {|tr| tr.locale == fallback }
85 translation && translation.send(attr_name)
92 result && Translation::Attribute.new(result, :locale => locale, :requested_locale => requested_locale)