复制 Rails I18n.t 方法

问题描述

使用 Rails 我们依赖于 I18n.t,也许 YAML 文件中配置的更多东西应该用类似的方法使用。

例如,我有一个包含冰淇淋价格的文件

icecreams:
  water:
    strawBerry: 5
    watermelon: 5
    peach: 6
  cream:
    chocolate: 7
    vanilla: 4
    lucuma: 8

我怎样才能像我们使用 I18n 那样获得任何冰淇淋的价格?

例如:icecreams('cream.lucuma')

解决方法

一个简单的方法应该是在初始化程序中加载 YAML 文件

初始化程序/icecreams.rb

file_path = File.read(File.expand_path('./config/icreams.yml'))
ICECREAMS = YAML.safe_load(file_path,[],true).with_indifferent_access

def icecreams(path)
  dig_path = path.split('.').map(&:to_sym)
  ICECREAMS.dig(*dig_path)
end

当然,我没有得到 I18n 的懒惰版本,但它已经足够好了。

,

使用 Lomefin 上面共享的相同代码,我为其添加了一个小的动态特性。

file_path = File.read(File.expand_path('./data.yaml'))
data = YAML.safe_load(file_path,true).with_indifferent_access

data.keys.each do |key|
  define_method(key) do |path|
    dig_path = path.split('.').map(&:to_sym)
    data[key].dig(*dig_path)
  end   
end

假设 yaml 文件在根节点上进一步扩展,

icecreams:
  water:
    strawberry: 5
    watermelon: 5
    peach: 6
  cream:
    chocolate: 7
    vanilla: 4
    lucuma: 8
languages:
  ruby:
    rails: 0
    sinatra: 1

现在您可以从 yaml 文件访问所有这些值。

2.5.1 :011 > languages('ruby.rails')
 => 0
2.5.1 :012 > languages('ruby.sinatra')
 => 1
2.5.1 :013 > icecreams('water.strawberry')
 => 5
2.5.1 :014 > icecreams('cream.chocolate')
 => 7