我升级到rails 3.0.9并且有一个新的yaml gem。不幸的是,to_yaml输出相当大的哈希的方式已经发生了某种变化。现在,我得到了很多“!map:ActiveSupport :: HashWithIndifferentAccess”之前我没有得到的元素,据我所知,这是一个bug,因为我试图使我的.yml尽可能易读。有没有办法摆脱yaml输出中的“!map:ActiveSupport :: HashWithIndifferentAccess”?它不会影响它加载到我的代码中的方式,所以我没有看到在输出中有它的点。我可以把它搞定,但我认为这里还有其他一些我不知道的事情。
典型的哈希输入:
{"All" =>
{"A test" => {"string"=>"This is just a test",
"description" => "This is a description for a test string",
"alternatives" => [{"new" => "woot"}]}}
Yaml输出:
All:
A test: !map:ActiveSupport::HashWithIndifferentAccess
string: This is just a test
description: This is a description for a test string
alternatives:
- !map:ActiveSupport::HashWithIndifferentAccess
new: woot
我想要的(以及我以前得到的):
All:
A test:
string: This is just a test
description: This is a description for a test string
alternatives:
- new: woot
注意:我的输出必须是UTF-8。
答案 0 :(得分:4)
我怀疑你的哈希值来自控制器中的params
,其类型为ActiveSupport::HashWithIndifferentAccess
。修复输出的一种方法是通过猴子修补其to_yaml
方法,将其转换为普通哈希值,然后再将其转换为YAML。
# config/initializers/hash_with_indifferent_access.rb
class HashWithIndifferentAccess < Hash
def to_yaml(opts = {})
self.to_hash.to_yaml(opts)
end
end
答案 1 :(得分:2)
我在同一个问题上,我一直在思考 @htanata 解决方案,也可以实现这个猴子补丁:
class HashWithIndifferentAccess < Hash
def to_yaml_typea
""
end
end
但这也很危险。
我一直在考虑实施我的own YAML::Emitter,但它看起来像技术过度。
这也有效:
JSON.parse(my_hash_with_indifferent_access.to_json).to_yaml
但看起来效率不高:)
我也想到了:
my_hash_with_indifferent_access.to_yaml.gsub( " !map:ActiveSupport::HashWithIndifferentAccess", "" )
仍在思考是否有可能,但我们所有人都认为这闻起来很糟糕。
我的最终解决方案是:
# config/intializers/hash_with_indifferent_access_extension.rb
# use it like `params.to_hash_recursive.to_yaml`
class HashWithIndifferentAccess < Hash
def to_hash_recursive
result = self.to_hash
result.each do |key, value|
if(value.is_a? HashWithIndifferentAccess)
result[key] = value.to_hash_recursive
end
end
result
end
end
它也是一个猴子补丁,但至少它是猴子修补不存在的方法,所以干扰第三方代码行为的可能性非常奇怪。 / p>
PD :有关清理此代码的任何建议,请参阅gist