Oh!Coder

Coding Life

Config Gem简介

| Comments

这次跟大家介绍的gem名字叫Config。顾名思义,config可以帮助你在不同环境下配置简单并且可重用的设置。

特性

  • 简单的YAML配置文件
  • 支持ERB的配置文件
  • 支持继承的配置文件
  • 通过便捷的对象成员访问配置信息

兼容性

  • Ruby 2.x
  • Rails >= 3.1以及4
  • Padrino
  • Sinatra

对于更老的Rails版本以及其它Ruby app,可以使用AppConfig

在Rails 3或4下进行安装

Gemfile中添加如下代码:

1
gem "config"

如果你想在rails初始化之前使用Settings,可以在初始化配置文件中做如下手动设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module Appname
  class Application < Rails::Application

    Bundler.require(*Rails.groups)
    Config::Integration::Rails::Railtie.preload

    # ...

    config.time_zone = Settings.time_zone

    # ...

  end
end

在Padrino中进行安装

Gemfile中添加如下一行:

1
gem "config"

在此之前,在app.rb文件中,需要对Config进行register操作

1
register Config

在Sinatra中进行安装

Gemfile中添加如下一行:

1
gem "config"

在此之前,需要对Config进行register操作。需要在文件中设定一个root目录,以便于它能找到配置文件。

1
2
set :root, File.dirname(__FILE__)
register Config

如果你想通过给定几个yml加载的路径,也可以在你的配置代码块中进行手动初始化。

1
Config.load_and_set_settings("/path/to/yaml1", "/path/to/yaml2", ...)

自定义配置

也可以通过生成一个初始化文件,然后自定义Config的行为:

1
rails g config:install

上面这行代码将会生成config/initializers/config.rb文件,其中包括一些默认的设置。与此同时,也会对应的生成不同运行环境下的配置文件:

1
2
3
4
config/settings.yml
config/settings/development.yml
config/settings/production.yml
config/settings/test.yml

访问Settings对象

安装完这个plugin之后,Settings对象就可以在全局范围内使用。可以通过对象成员标记进行访问:

1
Settings.my_config_entry

支持嵌套:

1
Settings.my_section.some_entry

或者说,如果你一开始并不能确定需要配置哪些参数,也可以使用[]操作符对标示符进行动态访问。

1
2
3
4
# All the following are equivalent to Settings.my_section.some_entry
Settings.my_section[:some_entry]
Settings.my_section['some_entry']
Settings[:my_section][:some_entry]

如果你在初始化配置文件中设置了不同的常量名,可以直接替换上面例子中的标示符。

一般配置文件

Config的实例全部来自下面文件的编译:

1
2
3
4
5
6
7
config/settings.yml
config/settings/#{environment}.yml
config/environments/#{environment}.yml

config/settings.local.yml
config/settings/#{environment}.local.yml
config/environments/#{environment}.local.yml

文件中对Settings的定义,更低层的覆盖高级别的列表。

重新加载settings

可以通过运行Settings.reload!在任何时间加载Settings对象。

重新加载settings和config文件

在运行的时候,可以从不同的config文件中重新加载Settings对象。

比如说,你想对生产环境进行测试,可以:

1
2
3
4
5
6
Rails.env = "production"
Settings.reload_from_files(
  Rails.root.join("config", "settings.yml").to_s,
  Rails.root.join("config", "settings", "#{Rails.env}.yml").to_s,
  Rails.root.join("config", "environments", "#{Rails.env}.yml").to_s
)

特定环境的配置文件

你可以在特定环境下拥有配置文件。特定环境的配置要比普通的配置文件优先级要高。

比如说开发环境配置文件:

1
#{Rails.root}/config/environments/development.yml

生产环境下的配置文件:

1
#{Rails.root}/config/environments/production.yml

开发者指定特定文件

如果你想能够进行本地配置,特别是在你的机器上或开发环境下,可以使用如下文件,这些文件自动被git忽略:

1
2
3
Rails.root.join("config", "settings.local.yml").to_s,
Rails.root.join("config", "settings", "#{Rails.env}.local.yml").to_s,
Rails.root.join("config", "environments", "#{Rails.env}.local.yml").to_s

运行期间添加源

可以在运行期间添加YAML配置文件:

1
2
Settings.add_source!("/path/to/source.yml")
Settings.reload!

执行完上面两行代码,名为source.yml的文件就会覆盖之前已经加载的那个。

另外,你可以预先加载一个YML文件:

1
2
Settings.prepend_source!("/path/to/source.yml")
Settings.reload!

这个功能和add_source一样,但是对于给定的YML文件是最先加载(而不是后加载),加载完成之后会被后来其它配置文件所覆盖。这对于想实现默认设置的功能非常有用。

对于我自己的Rails项目,有一件事情我特别喜欢做,那就是提供一个.gitignored文件忽略的local.yml配置文件(当然,关于这一点每个开发人员有各自的癖好)。那么可以在config/initializers/add_local_config.rb文件中创建一个新的初始化文件。

1
2
Settings.add_source!("#{Rails.root}/config/settings/local.yml")
Settings.reload!

嵌入Ruby(ERB)

在配置文件中允许嵌入Ruby。详见如下案例。

访问Settings的配置

考虑下面的两个配置文件。

  • #{Rails.root}/config/settings.yml
1
2
size: 1
server: google.com
  • #{Rails.root}/config/environments/development.yml
1
2
3
4
5
size: 2
computed: <%= 1 + 2 + 3 %>
section:
  size: 3
  servers: [ {name: yahoo.com}, {name: amazon.com} ]

注意,特定的环境配置会覆盖通用的配置。

1
2
Settings.size   # => 2
Settings.server # => google.com

注意嵌入的Ruby。

1
Settings.computed # => 6

注意,对象成员标示即便是嵌套也可以进行维护。

1
Settings.section.size # => 3

注意数组标示和对象成员标示都可以被维护。

1
2
Settings.section.servers[0].name # => yahoo.com
Settings.section.servers[1].name # => amazon.com

在Heroku下工作

Heroku使用ENV对象来存储敏感设定,比如上面提到的本地文件描述。你不能把此类文件上传到Heroku的原因是因为这是一个临时的文件系统,每一次从git源refresh一次,文件系统都会重新创建。

在Heroku下使用config,只需要在config/initializers/config.rb文件中,把use_env变量设置成true。例如:

1
2
3
4
Config.setup do |config|
  config.const_name = 'AppSettings'
  config.use_env = true
end

现在可以从ENV对象中读取变量到settings中了。对于上面的例子,会寻找前缀为’AppSettings’开始的标示符。比如:

1
2
ENV['AppSettings.section.size'] = 1
ENV['AppSettings.section.server'] = 'google.com'

但是不能和数组一起工作。

上传本地文件到Heroku可以运行bundle exec rake config:heroku

更多

更多更新的内容,可参见原文档

Comments