So... First, I should make my goal clear. My goal is to have an environment defined constant filled with attributes from a yaml file that my app can reference.
The simplest example I can give is something like this:
# initalizers/config.rb
CONFIG = YAML.load_file("#{Rails.root}/config/config.yml")[RAILS_ENV]
# config.yml:
production:
host:
foo.com
development:
host:
localhost
port:
3000
# config/environments/development.rb
Foo::Application.configure do
#...
config.action_mailer.default_url_options = { :host => CONFIG[:host], :port => CONFIG[:port] }
config.after_initialize do
Rails.application.routes.default_url_options = { :host => CONFIG[:host], :port => CONFIG[:port] }
end
end
My problems are:
The constant "CONFIG" does not exist prior to the after_initialize block (obviously because CONFIG is s开发者_StackOverflowet as part of the initialize process), so I need to move this into the after_initialize block, but I cannot reference "config.action_mailer" inside the after_initialize block because "config" does not exist in that scope... Which is really confusing to me. Shouldn't "config" be accessible inside the block since it exists outside of it?
And as a side question, I am really really really confused how this config.x business works. The block is not yielding any variables so, how is "config" even valid in the context of Foo::Application.configure ?
I would think for it to work at all that it should be:
Foo::Application.configure do |config|
But that's not the case, so I really am curious how this works..
If you define your configuration loader inside of config/application.rb
instead of an initializer you should be able to pre-empt the call to configure
and have everything set up in time.
Sometimes it's best to make a sub-class that handles configuration files. A very basic example is this:
class Foo::Configuration
def initialize
# Read in contents of config file
end
def method_missing(name)
@config[name.to_s]
end
end
Then in your application you define a method like this:
class Foo::Application
def self.config
@config ||= Foo::Configuration.new
end
end
This will auto-load as required. It also avoids having a messy constant that shows up in the context of every single object.
精彩评论