A clean way to handle custom configuration values
In any Ruby app (not only Rails)
And without using method_missing
- does it use the dot-env file ENV variable?
- does it use the Docker ENV variable?
- does it use the server set ENV variable?
- what is the load order of initializers?
- rely on configuration values set in your code
- don't fail silently on typos
- use default values
- use objects, not only strings
- setting values is simple
- no need to add another gem to your codebase
- use the same mechanism regardless of the environment
- keep the overview
- understand the mechanism
- add custom methods easily
- load it before anything else
There is not much code to show, so I will show it.
# class Settings
#
def self.register(var_name)
define_singleton_method(var_name) {
instance_variable_get("@#{var_name}")
}
instance_variable_set("@#{var_name}",
ENV.fetch(var_name.to_s.upcase))
end
# class Settings
#
def self.register(var_name, default: nil)
define_singleton_method(var_name) {
instance_variable_get("@#{var_name}")
}
instance_variable_set("@#{var_name}",
ENV.fetch(var_name.to_s.upcase, default))
end
# Set custom configuration variable with default:
#
# uses default unless ENV["API_URL"] is set
#
register :api_url, default: "http://localhost:4567/api"
# Access:
#
Settings.api_url
# class Settings
#
def self.register(var_name, default: nil)
define_singleton_method(var_name) {
instance_variable_get("@#{var_name}")
}
instance_variable_set("@#{var_name}",
ENV.fetch(var_name.to_s.upcase, default))
end
# class Settings
#
def self.register(var_name, default: nil)
define_singleton_method(var_name) {
instance_variable_get("@#{var_name}")
}
set(var_name, ENV.fetch(var_name.to_s.upcase, default))
end
def self.set(var_name, value)
instance_variable_set("@#{var_name}", value)
end
# overwrite registered variables:
#
Settings.set :access_locked, true
if ENV["PRINT_STACKTRACE"]
# ...
export PRINT_STACKTRACE=false
def self.is?(var_name, other_value)
public_send(var_name.to_sym).to_s == other_value.to_s
end
if Settings.is?(:print_stacktrace, true)
# ...
- all custom configuration values are declared in one file
- the code is easily grep-able for their usage
- load order is clear
- use the same mechanism regardless of the framework
Find this presentation
and several code
examples
under: https://github.com/mediafinger/settings