-
-
Save railyboy/3706025 to your computer and use it in GitHub Desktop.
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 |
# 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 |
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 > |
# 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 | |
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
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
File locations
lib/generic_search/app_data.rb
config/initializers/deep_symbolizable.rb
config/initializers/search_configurations.yml