[英]Ruby thread-safe class variables
I have a number of models that load a collection of strings, based on the user's i18n locale. 我有许多基于用户的i18n语言环境加载字符串集合的模型。 In order to simplify things, each model that does so includes the following module:
为了简化操作,每个模型都包括以下模块:
module HasStrings
def self.included(klass)
klass.extend ClassMethods
end
module ClassMethods
def strings
@strings ||= reload_strings!
end
def reload_strings!
@strings =
begin
File.open(RAILS_ROOT / 'config' / 'locales' / self.name.pluralize.downcase / I18n.locale.to_s + ".yml") { |f| YAML.load(f) }
rescue Errno::ENOENT
# Load the English strings if the current language doesn't have a strings file
File.open(RAILS_ROOT / 'config' / 'locales' / self.name.pluralize.downcase / 'en.yml') { |f| YAML.load(f) }
end
end
end
end
I am running into a problem, however, because @strings
is a class variable, and thus, the strings from one person's chosen locale are "bleeding" over into another user with a different locale. 但是,我遇到了一个问题,因为
@strings
是一个类变量,因此,一个人选择的语言环境中的字符串被“渗出”到另一个具有不同语言环境的用户中。 Is there a way to setup the @strings
variable so that it lives only within the context of the current request? 有没有办法设置
@strings
变量,使其只存在于当前请求的上下文中?
I tried replacing @strings
with Thread.current["#{self.name}_strings"]
(so that there's a different thread variable per class), but in that case the variable was retained over multiple requests and strings weren't reloaded when the locale was changed. 我尝试用
Thread.current["#{self.name}_strings"]
替换@strings
(这样每个类都有一个不同的线程变量),但是在那种情况下,该变量保留在多个请求中,并且当语言环境已更改。
I see two options. 我看到两个选择。 The first is to make @strings an instance variable.
首先是使@strings成为实例变量。
But then you may be loading them more than once on a single request, so instead, you can turn @strings into a hash of locale against a string set. 但是随后您可能会在单个请求中多次加载它们,因此,您可以将@strings转换为针对字符串集的语言环境哈希。
module HasStrings
def self.included(klass)
klass.extend ClassMethods
end
module ClassMethods
def strings
@strings ||= {}
string_locale = File.exists?(locale_filename(I18n.locale.to_s)) ? I18n.locale.to_s : 'en'
@strings[string_locale] ||= File.open(locale_filename(string_locale)) { |f| YAML.load(f) }
end
def locale_filename(locale)
"#{RAILS_ROOT}/config/locales/#{self.name.pluralize.downcase}/#{locale}.yml"
end
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.