在 Rails 中加载 YML 文件,可能使用 i18n 文件代替 [英] Loading a YML file in Rails, and maybe using a i18n file instead
问题描述
我有一个 dropdown.yml 文件,用于存储表单中多选字段的所有下拉值.它不依赖于环境,所以我没有 :development, :production 等.
I have a dropdown.yml file that stores all my dropdown values for my multi-select fields in my forms. It is not environment dependent, so I do not have :development, :production, etc.
我想将文件缓存到一个常量中,以便我可以在我的应用程序中使用.我找到了这个命令.
I would like cache the file into a constant so I can use across my app. I found this command.
config = Rails.application.config_for(:payment)
但是,它看起来是依赖于环境的.添加 yml 的最佳方法是什么?
However, it looks like it is environment dependent. What is the best way to add the yml?
第二,我应该为此使用语言环境而不是自定义 yml 文件吗?
Second, should I use locales for this instead of a custom yml file?
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?
So that I could reference field1, from any of the name keys, car_model, truck_model, or bike_model?
推荐答案
我想我会为此创建一个实用程序类和模块.类似的东西:
I think I would make a utility class and module for this. Something like:
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
扩展了模型哈希,因此您也可以这样做:
You'll notice I extended the model hash with a custom DropdownExt
, so you can also do:
Dropdowns.car_model.field1
=> {"yes"=>"true", "no"=>"false"}
Dropdowns.car_model.field1.yes
=> "true"
Dropdowns.car_model.region.US
=> United States
当您在一个实例上执行 extend(SomeModule)
时,只有该实例会使用模块进行扩展,因此您不会在整个过程中污染 Hash
(在这种情况下)您的整个应用程序.
When you do extend(SomeModule)
on an instance, then only that instance is extended with the module so you don't polute Hash
(in this case) throughout your entire application.
IMO,使用 config
似乎有点太低级了.但是,我意识到这是个人喜好的问题.此外,这会为您节省一点打字时间.
IMO, using config
seems a little too low-level. But, I realize that's a matter of personal preference. Also, this will save you a little typing.
这种方法的另一个优点是您可以免费"获得每个模型的类方法.所以你可以这样做:
Another advantage of this approach is that you get the class methods for each of your models "for free". So you can do:
Dropdowns.car_model
代替
Rails.application.config.dropdown[:car_model]
我不知道.这对我来说似乎更好.
I don't know. That just seems nicer to me.
最后,我想我喜欢将整个事情封装在一个类中.再次,个人喜好问题.但是,这对我来说似乎更像红宝石.
Finally, I guess I like encapsulating the whole thing in a class. Again, a matter of personal preference. But, that seems more ruby-ish to me.
顺便说一句,我的 YAML 想要将您的 yes
和 no
更改为 true
和 false
.所以,我做到了:
BTW, my YAML was wanting to change your yes
and no
to true
and false
. So, I did:
---
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"}}
这篇关于在 Rails 中加载 YML 文件,可能使用 i18n 文件代替的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!