Yaml输出填充了!map:ActiveSupport :: HashWithIndifferentAccess

时间:2011-07-05 04:37:09

标签: ruby-on-rails-3 utf-8 yaml

我升级到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。

2 个答案:

答案 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