-
-
Save morhekil/3706140 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 | |
class Hash; include DeepSymbolizable; 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 | |
reload! does reload the application code indeed, but it does not always pickup changes made to you basic environment settings (such at the ones you do in config/application.rb or config/environments/*), and also I had it not reloading changes in initializers as well. Restarting the console helps in this cases, and sometimes it affects the server running dev environment, too - again, restarting the server helps.
Regarding placing your code in lib - of course, you can do it. You can put the code for the module itself in, say, lib/deep_symbolizable.rb, make sure it is required or auto-loaded, and include the method into Hash class in an initializer - basically just take the last line from deep_symbolizable.rb above and put it into config/initializers/app_data.rb, followed by loading of yml files.
Thanks
I can see I need to remove the class Hash I had in DeepSymbolizable (which I had put up near the top).
Another simple question. I thought in rails console (rails c) reload! reloaded the environment? I think part of my problem was that I assumed this would pick up changes I had made to the files (after saving), but when I had made all the changes they still didn't work with a simple reload!
I was getting the error:
1.9.3-p125 :026 > reload!
Reloading...
=> true
1.9.3-p125 :027 > AppData.load!("#{Rails.root}/config/initializers/search_configurations.yml")
NameError: uninitialized constant AppData
Have I misunderstood what reload! in Rails console does?
Also, if I want to store this code except the .yml file in lib what do I need to do? I assume its just setup the autoload which I already had?
Really appreciate your help on this