Rails 将 YAML 加载到哈希并按符号引用
我正在 Rails 3.0.9 中加载 YAML 文件,如下所示:
APP_CONFIG = YAML.load(File.read(File.expand_path('../app.yml', __FILE__)))
它加载所有内容,例如分层哈希,没问题。我不喜欢的部分是散列只能用单引号或双引号访问,而不能用符号访问。
APP_CONFIG['mailer']['username'] # works fine
APP_CONFIG[:mailer][:username] # doesn't
有什么想法吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
尝试使用 HashWithIn DifferentAccess 像
Try using the HashWithIndifferentAccess like
另一种解决方案是将您希望访问的键作为前面带有冒号的符号。例如:
稍后您可以像这样访问这些:
请注意,我正在使用
YAML::ENGINE.yamler = "syck"
。不确定这是否适用于psych
。 (Psych 肯定不会支持键合并,正如我在示例中所示的那样。)关于使用
HashWithIn DifferentAccess
: 使用它会产生创建重复键的副作用:一个用于符号访问和字符串访问。如果您将 YAML 数据作为数组传递,这可能是邪恶的。如果您采用该解决方案,请注意这一点。An alternative solution is to have the keys which you wish to access as a symbol prepended with a colon. For example:
Later you can then access these like so:
Note that I am using
YAML::ENGINE.yamler = "syck"
. Not sure if this works withpsych
. (Psych definitely won't support key merging as I showed in the example though.)About using
HashWithIndifferentAccess
: using it has the side effect of creating duplicate keys: one for symbol access and one for string access. This might be nefarious if you pass around YAML data as arrays. Be aware of this if you go with that solution.如果您使用 Ruby on Rails,您可能需要查看 symbolize_keys(),它完全符合OP的要求。如果哈希值很深,可以使用
deep_symbolize_keys()
。使用这种方法,答案是If you are working in Ruby on Rails, You might want to take a look at symbolize_keys(), which does exactly what the OP asked for. If the hash is deep,you can use
deep_symbolize_keys()
. Using this approach, the answer isPsych(又名 YAML)提供关键字参数
:symbolize_names
将键加载为符号。 查看方法参考Psych (a.k.a. YAML) provides the keyword argument
:symbolize_names
to load keys as symbols. See method reference这与所选答案相同,但语法更好:
This is the same from the selected answer, but with a better syntax:
我在挖掘时发现了另一个潜在的答案。
您可以放弃 HashWithIn DifferentAccess.new,而是将其添加到 YAML 文件的顶部:
然后像平常一样简单地 YAML.load 。唯一的技巧是,如果您在环境中执行此操作以用于初始化程序等(就像我一样),则需要已经加载 Rails。
There is another potential answer I discovered while digging around.
You can forgo HashWithIndifferentAccess.new by instead adding this to the top of your YAML files:
then simply YAML.load like normal. The only trick is that rails needs to already be loaded if you are doing this in your environment for use in initializers, etc. (like I am).
我会写得这么简单:
YAML::load_file('app.yml').symbolize_keys
I'd write it that simple:
YAML::load_file('app.yml').symbolize_keys
只需在 YAML 解析器中使用适当的选项即可。例如,Psych 中的
symbolize_names
:请参阅 RDoc:https://ruby-doc.org/stdlib-2.6.1/libdoc/psych/rdoc/Psych.html#method-c-load。
Just use appropriate option in your YAML parser. For instance,
symbolize_names
in Psych:See RDoc: https://ruby-doc.org/stdlib-2.6.1/libdoc/psych/rdoc/Psych.html#method-c-load.
如果您使用纯 Ruby(即没有 Rails),您可以中间更改为 JSON 格式。 JSON 库的
parse
方法可以对键进行符号化。http://ruby-doc .org/stdlib-2.0.0/libdoc/json/rdoc/JSON.html#method-i-parse
这就是我的意思:
注意:这会增加转换的开销json。
If you're using pure Ruby (i.e. no Rails), you could intermediately change to JSON format. The JSON lib's
parse
method can symbolize keys.http://ruby-doc.org/stdlib-2.0.0/libdoc/json/rdoc/JSON.html#method-i-parse
Here's what I mean:
Note: This adds overhead of conversion to and from json.
您可能已经习惯了 Rails 中的 params hash,它实际上是一个 HashWithIn DifferentAccess 而不是标准的 ruby Hash 对象。这允许您使用“action”等字符串或“:action”等符号来访问内容。
使用 HashWithIn DifferentAccess,无论您使用什么,您都会得到相同的结果,但请记住,这仅适用于 HashWithIn DifferentAccess 对象。
因此,要使用 YAML 进行此操作,您必须将 YAML.load 的结果加载到 HashWithIn DifferentAccess 中,如下所示:
You are probably used to the params hash in Rails, which is actually a HashWithIndifferentAccess rather than a standard ruby Hash object. This allows you to use either strings like 'action' or symbols like :action to access the contents.
With a HashWithIndifferentAccess, you will get the same results regardless of what you use, but keep in mind this only works on HashWithIndifferentAccess objects.
So to make this work with YAML, you'll have to load the result of YAML.load into a HashWithIndifferentAccess, like so:
我通常不会使用
HashWithIn DifferentAccess
只是为了避免混淆并防止访问方式不一致,所以我会做的是附加.deep_symbolize_keys
来获取整个事情都是符号键形式的。I usually don't use
HashWithIndifferentAccess
just to avoid confusion and prevent inconsistencies in the way that it is accessed, so what I would do instead is tack on a.deep_symbolize_keys
to get the whole thing in symbol key form.