huacnlee / rails-settings-cached

Global settings for your Rails application.
Other
1.06k stars 202 forks source link

从设置取得值和拿到的不一致 #224

Closed icyleaf closed 3 years ago

icyleaf commented 3 years ago

问题描述:

我从 ENV['DEFAULT_LOCALE'] 取值来设置语言,从 Rails 配置和 i18n 拿到的值都是正确的,但从 RailsSettingCache 拿到的值却不一样,这里可以排除的没有在 db 里面,也尝试清除了 cache

配置代码:

# config/application.rb
class Application < Rails::Application
  locale = ENV['DEFAULT_LOCALE']&.to_sym
  config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
  config.i18n.available_locales = [:'zh-CN', :en]
  config.i18n.default_locale = config.i18n.available_locales.include?(locale) ? locale : :'zh-CN'
end

# app/models/setting.rb
class Setting < RailsSettings::Base
  field :site_locale, default: I18n.default_locale.to_s, type: :string, display: true,
           validates: { presence: true, inclusion: { in: I18n.available_locales.map(&:to_s) } }
end

结果表现:

[1] pry(main)> ENV['DEFAULT_LOCALE']
=> "zh-CN"
[2] pry(main)> Rails.configuration.i18n.default_locale
=> :"zh-CN"
[3] pry(main)> I18n.default_locale
=> :"zh-CN"
[4] pry(main)> Setting.site_locale
  Setting Load (0.4ms)  SELECT var, value FROM "settings"
=> "en"
[5] pry(main)> Setting.get_field 'site_locale'
=> {:scope=>:general, :key=>"site_locale", :default=>"en", :type=>:string, :readonly=>false, :options=>{:display=>true}}
[6] pry(main)> Setting.find_by(var: 'site_locale')
  Setting Load (0.3ms)  SELECT "settings".* FROM "settings" WHERE "settings"."var" = $1 LIMIT $2  [["var", "site_locale"], ["LIMIT", 1]]
=> nil
[7] pry(main)> Setting.clear_cache
=> false
[9] pry(main)> Setting.clear_cache!
=> nil
[10] pry(main)> Setting.get_field 'site_locale'
=> {:scope=>:general, :key=>"site_locale", :default=>"en", :type=>:string, :readonly=>false, :options=>{:display=>true}}

预期结果:

zh-CN

得到结果:

en

额外还有个诡异的问题,目前不知道咋复现,我配置了 validates 是获取 I18n.available_locales 的值,但在 docker 产品环境只能拿到 en,而没有 zh-CN

huacnlee commented 3 years ago

你的 I18n.default_locale 来自于 ENV,这个和启动周期有关系,你应该把 default 配置成 lambda 才可以。

field :site_locale, default: -> { I18n.default_locale.to_s }
icyleaf commented 3 years ago

还有一种方式是直接用 Rails.configuration.i18n 取值也可以。