Created
September 12, 2012 11:20
-
-
Save railyboy/3706025 to your computer and use it in GitHub Desktop.
Loading .yml configuration data with the code from http://speakmy.name/2011/05/29/simple-configuration-for-ruby-apps
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module AppData | |
#require 'deep_symbolizable' | |
# again - it's a singleton, thus implemented as a self-extended module | |
extend self | |
@_settings = {} | |
attr_reader :_settings | |
# This is the main point of entry - we call Settings.load! and provide | |
# a name of the file to read as it's argument. We can also pass in some | |
# options, but at the moment it's being used to allow per-environment | |
# overrides in Rails | |
def load!(filename, options = {}) | |
newsets = YAML::load_file(filename).deep_symbolize | |
newsets = newsets[options[:env].to_sym] if \ | |
options[:env] && \ | |
newsets[options[:env].to_sym] | |
deep_merge!(@_settings, newsets) | |
end | |
# Deep merging of hashes | |
# deep_merge by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809 | |
def deep_merge!(target, data) | |
merger = proc{|key, v1, v2| | |
Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 } | |
target.merge! data, &merger | |
end | |
def method_missing(name, *args, &block) | |
@_settings[name.to_sym] || | |
fail(NoMethodError, "unknown configuration root #{name}", caller) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Symbolizes all of hash's keys and subkeys. | |
# Also allows for custom pre-processing of keys (e.g. downcasing, etc) | |
# if the block is given: | |
# | |
# somehash.deep_symbolize { |key| key.downcase } | |
# | |
# Usage: either include it into global Hash class to make it available to | |
# to all hashes, or extend only your own hash objects with this | |
# module. | |
# E.g.: | |
# 1) class Hash; include DeepSymbolizable; end | |
# 2) myhash.extend DeepSymbolizable | |
module DeepSymbolizable | |
class Hash | |
include DeepSymbolizable | |
end | |
def deep_symbolize(&block) | |
method = self.class.to_s.downcase.to_sym | |
syms = DeepSymbolizable::Symbolizers | |
syms.respond_to?(method) ? syms.send(method, self, &block) : self | |
end | |
module Symbolizers | |
extend self | |
# the primary method - symbolizes keys of the given hash, | |
# preprocessing them with a block if one was given, and recursively | |
# going into all nested enumerables | |
def hash(hash, &block) | |
hash.inject({}) do |result, (key, value)| | |
# Recursively deep-symbolize subhashes | |
value = _recurse_(value, &block) | |
# Pre-process the key with a block if it was given | |
key = yield key if block_given? | |
# Symbolize the key string if it responds to to_sym | |
sym_key = key.to_sym rescue key | |
# write it back into the result and return the updated hash | |
result[sym_key] = value | |
result | |
end | |
end | |
# walking over arrays and symbolizing all nested elements | |
def array(ary, &block) | |
ary.map { |v| _recurse_(v, &block) } | |
end | |
# handling recursion - any Enumerable elements (except String) | |
# is being extended with the module, and then symbolized | |
def _recurse_(value, &block) | |
if value.is_a?(Enumerable) && !value.is_a?(String) | |
# support for a use case without extended core Hash | |
value.extend DeepSymbolizable unless value.class.include?(DeepSymbolizable) | |
value = value.deep_symbolize(&block) | |
end | |
value | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
marks-imac:lib railsdev$ pwd | |
/Users/railsdev/Development/railsprojects/Learning/Marks-Attempts/Test-Area/bootstrap-dropdown-buttons/lib | |
marks-imac:lib railsdev$ cd generic_search/ | |
marks-imac:generic_search railsdev$ rails c | |
Loading development environment (Rails 3.2.5) | |
1.9.3-p125 :001 > AppData.load!("#{Rails.root}/config/initializers/search_configurations.yml") | |
NameError: uninitialized constant AppData | |
from (irb):1 | |
from /Users/railsdev/.rvm/gems/ruby-1.9.3-p125@bootstrap-dropdown-buttons/gems/railties-3.2.5/lib/rails/commands/console.rb:47:in `start' | |
from /Users/railsdev/.rvm/gems/ruby-1.9.3-p125@bootstrap-dropdown-buttons/gems/railties-3.2.5/lib/rails/commands/console.rb:8:in `start' | |
from /Users/railsdev/.rvm/gems/ruby-1.9.3-p125@bootstrap-dropdown-buttons/gems/railties-3.2.5/lib/rails/commands.rb:41:in `<top (required)>' | |
from script/rails:6:in `require' | |
from script/rails:6:in `<main>' | |
1.9.3-p125 :002 > GenericSearch::AppData.load!("#{Rails.root}/config/initializers/search_configurations.yml") | |
LoadError: Expected /Users/railsdev/Development/railsprojects/Learning/Marks-Attempts/Test-Area/bootstrap-dropdown-buttons/lib/generic_search/app_data.rb to define GenericSearch::AppData | |
from /Users/railsdev/.rvm/gems/ruby-1.9.3-p125@bootstrap-dropdown-buttons/gems/activesupport-3.2.5/lib/active_support/dependencies.rb:503:in `load_missing_constant' | |
from /Users/railsdev/.rvm/gems/ruby-1.9.3-p125@bootstrap-dropdown-buttons/gems/activesupport-3.2.5/lib/active_support/dependencies.rb:192:in `block in const_missing' | |
from /Users/railsdev/.rvm/gems/ruby-1.9.3-p125@bootstrap-dropdown-buttons/gems/activesupport-3.2.5/lib/active_support/dependencies.rb:190:in `each' | |
from /Users/railsdev/.rvm/gems/ruby-1.9.3-p125@bootstrap-dropdown-buttons/gems/activesupport-3.2.5/lib/active_support/dependencies.rb:190:in `const_missing' | |
from (irb):2 | |
from /Users/railsdev/.rvm/gems/ruby-1.9.3-p125@bootstrap-dropdown-buttons/gems/railties-3.2.5/lib/rails/commands/console.rb:47:in `start' | |
from /Users/railsdev/.rvm/gems/ruby-1.9.3-p125@bootstrap-dropdown-buttons/gems/railties-3.2.5/lib/rails/commands/console.rb:8:in `start' | |
from /Users/railsdev/.rvm/gems/ruby-1.9.3-p125@bootstrap-dropdown-buttons/gems/railties-3.2.5/lib/rails/commands.rb:41:in `<top (required)>' | |
from script/rails:6:in `require' | |
from script/rails:6:in `<main>' | |
1.9.3-p125 :003 > GenericSearch | |
=> GenericSearch | |
1.9.3-p125 :004 > AppData.load!("#{Rails.root}/config/initializers/search_configurations.yml") | |
NoMethodError: undefined method `deep_symbolize' for #<Hash:0x007fe146e2abd8> | |
from /Users/railsdev/Development/railsprojects/Learning/Marks-Attempts/Test-Area/bootstrap-dropdown-buttons/lib/generic_search/app_data.rb:16:in `load!' | |
from (irb):4 | |
from /Users/railsdev/.rvm/gems/ruby-1.9.3-p125@bootstrap-dropdown-buttons/gems/railties-3.2.5/lib/rails/commands/console.rb:47:in `start' | |
from /Users/railsdev/.rvm/gems/ruby-1.9.3-p125@bootstrap-dropdown-buttons/gems/railties-3.2.5/lib/rails/commands/console.rb:8:in `start' | |
from /Users/railsdev/.rvm/gems/ruby-1.9.3-p125@bootstrap-dropdown-buttons/gems/railties-3.2.5/lib/rails/commands.rb:41:in `<top (required)>' | |
from script/rails:6:in `require' | |
from script/rails:6:in `<main>' | |
1.9.3-p125 :005 > |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Search Conditions | |
# manually configured | |
# | |
# EDIT with CARE | |
# | |
generic_conditions: | |
- contains | |
- equals | |
- 'starts with' | |
- 'ends with' | |
- 'from/to' | |
- 'matches' | |
models: | |
diagnosis: | |
fields: | |
- code | |
- description | |
conditions: | |
- contains | |
- equals | |
- 'starts with' | |
- 'ends with' | |
- 'from/to' | |
- 'matches' | |
services: | |
fields: | |
code: | |
- contains | |
- equals | |
- 'starts with' | |
- 'ends with' | |
- matches | |
description: | |
- 'valid from' | |
emails: | |
admin: [email protected] | |
support: [email protected] | |
urls: | |
search: http://google.com | |
blog: http://speakmy.name | |
you can just do the inclusion at the end of deep_symbolizable.rb, like here: https://gist.github.com/3706140
File locations in this case can be like this:
config/initializers/01_deep_symbolizable.rb
config/initializers/99_app_data.rb
config/data/search_configurations.yml
If will auto-load and execute deep_symbolizable.rb first, then app_data.rb - after that you can load your yml files. As app_data.rb is executed at the end - you can even load your data at the end of that file, as Hash should already be set up by that time
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Was this the correct place to put the class override?
module DeepSymbolizable
class Hash
include DeepSymbolizable
end
def deep_symbolize(&block)
method = self.class.to_s.downcase.to_sym
syms = DeepSymbolizable::Symbolizers
syms.respond_to?(method) ? syms.send(method, self, &block) : self
end