我有一个dropdown.yml文件,用于存储表单中多选字段的所有下拉值。它不依赖于环境,所以我没有:development,:production等。
我想将文件缓存到一个常量中,以便可以在我的应用程序中使用。我找到了这个命令。
config = Rails.application.config_for(:payment)
但是,它看起来像是取决于环境的。添加yml的最佳方法是什么?
第二,我应该为此使用语言环境而不是自定义的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了?
答案 0 :(得分:1)
将其加载到您的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]
也可以在应用程序中将其固定为常量。rb:
MY_CONST = HashWithIndifferentAccess.new(YAML.load_file(File.join(Rails.root, 'config', 'dropdown.yml')))
答案 1 :(得分:1)
我想我会为此制作一个实用程序类和模块。像这样:
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
似乎有点低级。但是,我意识到这是个人喜好问题。另外,这将为您节省一些打字输入。
此方法的另一个优点是您可以“免费”获得每个模型的类方法。因此,您可以这样做:
Dropdowns.car_model
代替
Rails.application.config.dropdown[:car_model]
我不知道。这对我来说似乎更好。
最后,我想我喜欢将整个内容封装在一个类中。同样,个人喜好问题。但是,这对我来说似乎更像红宝石。
顺便说一句,我的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"}}