-
-
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: someadmin@somewhere.net | |
| support: support@somewhere.net | |
| 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