rails:yml合并

时间:2011-03-31 05:49:54

标签: ruby-on-rails ruby yaml erb

假设我的rails配置有一个yml文件......

settings.yml中

defaults: &defaults
  interceptor_email: robot@wearemanalive.com

development:
  <<: *defaults

test:
  <<: *defaults

production:
  <<: *defaults

我希望有另一个yml文件,它不包含在版本控制中,每个开发人员都在本地维护...

user_settings.yml

development:
  interceptor_email: userfoo@domain.com

如何合并这些密钥?我正在用esb处理我的yml文件,所以这也是一个选项。只是无法弄清楚如何做到这一点。我有它的设置,所以如果我的环境缺少一个密钥,密钥会回退到默认值。

2 个答案:

答案 0 :(得分:6)

你不能分别阅读这两个yml文件吗?

settings = YAML.load(path_to_settings)[RAILS_ENV].symbolize_keys
user_settings = YAML.load(path_to_user_settings)[RAILS_ENV].symbolize_keys
settings.merge!(user_settings)

现在您应该拥有设置的哈希值,然后您可以根据需要合并哈希值。如果第二个哈希与第一个哈希具有相同的密钥,则第一个哈希将被覆盖。

答案 1 :(得分:1)

我就是这样做的(免责声明,我刚刚写了它,所以它还没有进行单元测试等等......我会更新它,因为我改进了它):

require 'yaml'

# read config files (currently only yaml supported), merge user config files over
# defaults and make the parsed data available to the rest of your application.
#
module YourNamespace class Config

   attr_reader :files, :get


   # Accepts a string filename or an array of string filenames to parse.
   # If an array is supplied, values from later files will override values
   # of earlier files with the same name.
   # Will choke if YAML.load_file returns false (invalid or empty file)

   #
   def initialize( files )

      @files = files.respond_to?( 'map' ) ? files : [ files ]

      @get   = @files                                             \
                                                                  \
         .map { | file | YAML.load_file file }                    \
         .reduce( {}, :merge! )

      ;

   end

end end

您可以这样称呼它:

config = YourNamespace::Config.new 'config.yml'

# or have the second one override the first
#
config = YourNamespace::Config.new [ 'config-defaults.yml', 'config.yml' ]

如果你想要看中,那里有很大的改进空间。理想情况下,将'Config'设置为不处理文件的接口,并在YamlConfigIniConfigCliConfigDbConfigCookieConfig中实现。这样,如果你有一天决定新的配置格式超级种子yaml是如此酷,你可以很容易地改变它而不会破坏任何东西。您可以让命令行配置选项轻松覆盖来自配置文件的选项。无论配置值来自何处,您都可以将配置模块重用于任何ruby项目。或者也许只是停止inventing hot water。快速浏览让我觉得那里有一些非常热的水......

接下来编写一些文档,单元测试,输入验证,错误处理,并为配置值创建一些花哨的读/写访问器。也许您希望能够像这样要求配置值,而不是一直编写数组和哈希值:

config.get 'app.component.section.setting' 

# or this if you want to keep them separate:
#
config.get( 'app', 'component', 'section', 'setting' )