Oh!Coder

Coding Life

Settingslogic Gem简介

| Comments

今天介绍的gem名字叫Settingslogic。总的来说是一个对关于ruby语言框架的项目起辅助配置功能的gem。

基本使用

简介

Settingslogic是一个简单的把ERB嵌入到YAML文件中的配置/设置功能的gem。对我们的app起到非常大的帮助。Settingslogic可以和除了Rails,Sinatra以外的任何Ruby框架结合。

安装

1
gem install settingslogic

1. 定义你的class

你需要完成的任务只有一个,那就是定义一个Settings常量。简单的像下面这样创建一个class:

1
2
3
4
class Settings < Settingslogic
  source "#{Rails.root}/config/application.yml"
  namespace Rails.env
end

此class命名为Settings,或Config,或任何你想使用的名称。根据你的喜好定义名字的长短。在一个rails应用中,比较好的创建位置是在app/models/settings.rb中。

我觉得应用中命名为settings,感觉更直观,少了一些困惑,多了一些灵活。

2.创建你的settings

注意上面我们提到的一个绝对路径指向一个名为”application.yml”的文件。这只是一个典型的YAML文件。还需要注意的是上面我们为开发环境指定的命名空间。命名空间是YAML文件中一个key相关的可选字符串。

使用命名空间允许我们根据开发环境变更我们的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# config/application.yml
defaults: &defaults
  cool:
    saweet: nested settings
  neat_setting: 24
  awesome_setting: <%= "Did you know 5 + 5 = #{5 + 5}?" %>

development:
  <<: *defaults
  neat_setting: 800

test:
  <<: *defaults

production:
  <<: *defaults

注意:某特定版本的Ruby/Bundler包括一个不能进行正确处理合并(比如上面的’«‘符号)的Psych YAML解析器。如果你的默认settings貌似被特定环境的设置所覆盖,那么把下面这行代码加到config/boot.rb文件中,即可解决此问题:

1
2
require 'yaml'
YAML::ENGINE.yamler= 'syck'

3.访问你的settings

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>> Rails.env
=> "development"

>> Settings.cool
=> "#<Settingslogic::Settings ... >"

>> Settings.cool.saweet
=> "nested settings"

>> Settings.neat_setting
=> 800

>> Settings.awesome_setting
=> "Did you know 5 + 5 = 10?"

可以在任何地方使用这些setting,比如在model中使用:

1
2
3
class Post < ActiveRecord::Base
  self.per_page = Settings.pagination.posts_per_page
end

4.可选/动态setting

经常,你会想要处理应用本身的一些全局默认设置,来降低settings的YAML文件中的变量个数。此时可以使用Hash的方式来访问这些可选配置:

1
2
3
4
5
6
7
8
9
10
11
>> Settings.messaging.queue_name
=> Exception: Missing setting 'queue_name' in 'message' section in 'application.yml'

>> Settings.messaging['queue_name']
=> nil

>> Settings.messaging['queue_name'] ||= 'user_mail'
=> "user_mail"

>> Settings.messaging.queue_name
=> "user_mail"

修改模型的例子:

1
2
3
class Post < ActiveRecord::Base
  self.per_page = Settings.posts['per_page'] || Settings.pagination.per_page
end

这就允许你只为posts的per_page,指定一个自定义的数值,又或者如果这个数值没有被指定,那么将设置回默认数值。

5.有条件的忽略异常

对缺少settings的参数抛出异常来帮助凸显配置问题。然而,在Rails应用的production环境下,对于因为缺少setting而返回nil的异常进行忽略还是有用的。因此在开发环境或者测试环境下停止运行并且凸显错误是有用的,但对于production环境却不是一个好的解决方法。

1
2
3
4
5
6
7
8
class Settings < Settingslogic
  source "#{Rails.root}/config/application.yml"
  namespace Rails.env
  suppress_errors Rails.env.production?
end

>> Settings.non_existent_key
=> nil

Sinatra / Capistrano / Vlad中的注意事项

其中每个framework都使用了一个set作为设置的约定,其实就是在全局对象空间中定义方法:

1
set :application, "myapp"  # does "def application" globally

因为这些方法是全局的,这回和Settingslogic引起冲突。幸运的是,解决方法是,只要在class中添加对load!方法的调用就可以:

1
2
3
4
5
class Settings < Settingslogic
  source "#{Rails.root}/config/application.yml"
  namespace Rails.env
  load!
end

通常情况下,在class中添加load!方法总是最安全的,因为这保证了settings在每一次都会被加载,而不是通过method_missing来惰性加载。

最后,还可以同样重新加载所有settings:

1
Settings.reload!

这对于想支持在不重新启动app的情况下重新加载修改了的YAML文件很有用。

更多

更详细,更新的相关信息可参见原文档

Comments