在 Rails 中加载 YML 文件,并可能改用 i18n 文件
Loading a YML file in Rails, and maybe using a i18n file instead
我有一个 dropdown.yml 文件,用于存储表单中多 select 字段的所有下拉值。它不依赖于环境,所以我没有 :development、:production 等
我想将文件缓存到一个常量中,以便我可以在我的应用程序中使用。我找到了这个命令。
config = Rails.application.config_for(:payment)
但是,它看起来像依赖于环境。添加 yml 的最佳方式是什么?
其次,我应该为此使用语言环境而不是自定义 yml 文件吗?
config/dropdown.yml
dropdown:
car_model:
field1:
yes: true
no: false
region:
US: United States
CA: Canada
此外,有没有一种方法可以从多个名称访问下拉菜单?
dropdown:
car_model| truck_model| bike_model:
field1:
yes: true
no: false
region:
US: United States
CA: Canada
这样我就可以从任何名称键 car_model、truck_model 或 bike_model?
中引用 field1
将其加载到配置块内的 application.rb:
class Application < Rails::Application
...
config.dropdowns = HashWithIndifferentAccess.new(YAML.load_file(File.join(Rails.root, 'config', 'dropdown.yml')))
...
end
通过`Rails.application.config.dropdown[:key]
在代码中使用
注意:我会删除顶级下拉键,或者将其添加到加载行的末尾,这样您就不需要在每次需要配置时都调用它。例如
HashWithIndifferentAccess.new(YAML.load_file(File.join(Rails.root, 'config', 'dropdown.yml')))[:dropdown]
也可以将它放入您的 application.rb 中的常量中:
MY_CONST = HashWithIndifferentAccess.new(YAML.load_file(File.join(Rails.root, 'config', 'dropdown.yml')))
我想我会为此制作一个实用程序 class 和模块。类似于:
module DropdownExt
def self.extended(receiver)
receiver.each do |k,v|
define_method(k) do
v.is_a?(Hash) ? v.extend(DropdownExt) : v
end
end
end
end
class Dropdowns
class << self
private
def dropdowns_spec
YAML.load_file("#{path}").with_indifferent_access
end
def path
Rails.root.join("spec/so/dropdowns/dropdowns.yaml") # <== you'll need to change this
end
end
dropdowns_spec[:dropdown].each do |k,v|
define_singleton_method k do
v.extend(DropdownExt)
end
end
%i(
truck_model
bike_model
).each do |to_alias|
singleton_class.send(:alias_method, to_alias, :car_model)
end
end
然后你可以这样做:
Dropdowns.car_model
=> {"field1"=>{true=>"true", false=>"false"}, "region"=>{"US"=>"United States", "CA"=>"Canada"}}
Dropdowns.truck_model
=> {"field1"=>{"yes"=>"true", "no"=>"false"}, "region"=>{"US"=>"United States", "CA"=>"Canada"}}
Dropdowns.bike_model
=> {"field1"=>{"yes"=>"true", "no"=>"false"}, "region"=>{"US"=>"United States", "CA"=>"Canada"}}
随心所欲。
你会注意到我用自定义 DropdownExt
扩展了模型哈希,所以你也可以这样做:
Dropdowns.car_model.field1
=> {"yes"=>"true", "no"=>"false"}
Dropdowns.car_model.field1.yes
=> "true"
Dropdowns.car_model.region.US
=> United States
当您对一个实例执行 extend(SomeModule)
时,只有该实例会使用模块进行扩展,因此您不会在整个应用程序中污染 Hash
(在这种情况下)。
IMO,使用config
似乎有点太低级了。但是,我意识到这是个人喜好的问题。此外,这将节省您的输入时间。
这种方法的另一个优点是您可以为每个模型 "for free" 获得 class 方法。所以你可以这样做:
Dropdowns.car_model
而不是
Rails.application.config.dropdown[:car_model]
我不知道。这对我来说似乎更好。
最后,我想我喜欢将整个东西封装在 class 中。同样,个人喜好问题。但是,这对我来说似乎更 ruby-ish。
顺便说一句,我的 YAML 想要将您的 yes
和 no
更改为 true
和 false
。所以,我做了:
---
dropdown:
car_model:
field1:
'yes': 'true'
'no': 'false'
region:
US: United States
CA: Canada
哪个返回
{"field1"=>{"yes"=>"true", "no"=>"false"}, "region"=>{"US"=>"United States", "CA"=>"Canada"}}
我有一个 dropdown.yml 文件,用于存储表单中多 select 字段的所有下拉值。它不依赖于环境,所以我没有 :development、:production 等
我想将文件缓存到一个常量中,以便我可以在我的应用程序中使用。我找到了这个命令。
config = Rails.application.config_for(:payment)
但是,它看起来像依赖于环境。添加 yml 的最佳方式是什么?
其次,我应该为此使用语言环境而不是自定义 yml 文件吗?
config/dropdown.yml
dropdown:
car_model:
field1:
yes: true
no: false
region:
US: United States
CA: Canada
此外,有没有一种方法可以从多个名称访问下拉菜单?
dropdown:
car_model| truck_model| bike_model:
field1:
yes: true
no: false
region:
US: United States
CA: Canada
这样我就可以从任何名称键 car_model、truck_model 或 bike_model?
中引用 field1将其加载到配置块内的 application.rb:
class Application < Rails::Application
...
config.dropdowns = HashWithIndifferentAccess.new(YAML.load_file(File.join(Rails.root, 'config', 'dropdown.yml')))
...
end
通过`Rails.application.config.dropdown[:key]
在代码中使用注意:我会删除顶级下拉键,或者将其添加到加载行的末尾,这样您就不需要在每次需要配置时都调用它。例如
HashWithIndifferentAccess.new(YAML.load_file(File.join(Rails.root, 'config', 'dropdown.yml')))[:dropdown]
也可以将它放入您的 application.rb 中的常量中:
MY_CONST = HashWithIndifferentAccess.new(YAML.load_file(File.join(Rails.root, 'config', 'dropdown.yml')))
我想我会为此制作一个实用程序 class 和模块。类似于:
module DropdownExt
def self.extended(receiver)
receiver.each do |k,v|
define_method(k) do
v.is_a?(Hash) ? v.extend(DropdownExt) : v
end
end
end
end
class Dropdowns
class << self
private
def dropdowns_spec
YAML.load_file("#{path}").with_indifferent_access
end
def path
Rails.root.join("spec/so/dropdowns/dropdowns.yaml") # <== you'll need to change this
end
end
dropdowns_spec[:dropdown].each do |k,v|
define_singleton_method k do
v.extend(DropdownExt)
end
end
%i(
truck_model
bike_model
).each do |to_alias|
singleton_class.send(:alias_method, to_alias, :car_model)
end
end
然后你可以这样做:
Dropdowns.car_model
=> {"field1"=>{true=>"true", false=>"false"}, "region"=>{"US"=>"United States", "CA"=>"Canada"}}
Dropdowns.truck_model
=> {"field1"=>{"yes"=>"true", "no"=>"false"}, "region"=>{"US"=>"United States", "CA"=>"Canada"}}
Dropdowns.bike_model
=> {"field1"=>{"yes"=>"true", "no"=>"false"}, "region"=>{"US"=>"United States", "CA"=>"Canada"}}
随心所欲。
你会注意到我用自定义 DropdownExt
扩展了模型哈希,所以你也可以这样做:
Dropdowns.car_model.field1
=> {"yes"=>"true", "no"=>"false"}
Dropdowns.car_model.field1.yes
=> "true"
Dropdowns.car_model.region.US
=> United States
当您对一个实例执行 extend(SomeModule)
时,只有该实例会使用模块进行扩展,因此您不会在整个应用程序中污染 Hash
(在这种情况下)。
IMO,使用config
似乎有点太低级了。但是,我意识到这是个人喜好的问题。此外,这将节省您的输入时间。
这种方法的另一个优点是您可以为每个模型 "for free" 获得 class 方法。所以你可以这样做:
Dropdowns.car_model
而不是
Rails.application.config.dropdown[:car_model]
我不知道。这对我来说似乎更好。
最后,我想我喜欢将整个东西封装在 class 中。同样,个人喜好问题。但是,这对我来说似乎更 ruby-ish。
顺便说一句,我的 YAML 想要将您的 yes
和 no
更改为 true
和 false
。所以,我做了:
---
dropdown:
car_model:
field1:
'yes': 'true'
'no': 'false'
region:
US: United States
CA: Canada
哪个返回
{"field1"=>{"yes"=>"true", "no"=>"false"}, "region"=>{"US"=>"United States", "CA"=>"Canada"}}