Class | Rails::Initializer |
In: |
vendor/rails/railties/lib/initializer.rb
|
Parent: | Object |
The Initializer is responsible for processing the Rails configuration, such as setting the $LOAD_PATH, requiring the right frameworks, initializing logging, and more. It can be run either as a single command that‘ll just use the default configuration, like this:
Rails::Initializer.run
But normally it‘s more interesting to pass in a custom configuration through the block running:
Rails::Initializer.run do |config| config.frameworks -= [ :action_mailer ] end
This will use the default configuration options from Rails::Configuration, but allow for overwriting on select areas.
configuration | [R] | The Configuration instance used by this Initializer instance. |
loaded_plugins | [R] | The set of loaded plugins. |
Create a new Initializer instance that references the given Configuration instance.
# File vendor/rails/railties/lib/initializer.rb, line 99 99: def initialize(configuration) 100: @configuration = configuration 101: @loaded_plugins = [] 102: end
Runs the initializer. By default, this will invoke the process method, which simply executes all of the initialization routines. Alternately, you can specify explicitly which initialization routine you want:
Rails::Initializer.run(:set_load_path)
This is useful if you only want the load path initialized, without incuring the overhead of completely loading the entire environment.
# File vendor/rails/railties/lib/initializer.rb, line 90 90: def self.run(command = :process, configuration = Configuration.new) 91: yield configuration if block_given? 92: initializer = new configuration 93: initializer.send(command) 94: initializer 95: end
# File vendor/rails/railties/lib/initializer.rb, line 239 239: def add_gem_load_paths 240: unless @configuration.gems.empty? 241: require "rubygems" 242: @configuration.gems.each &:add_load_paths 243: end 244: end
Adds all load paths from plugins to the global set of load paths, so that code from plugins can be required (explicitly or automatically via Dependencies).
# File vendor/rails/railties/lib/initializer.rb, line 235 235: def add_plugin_load_paths 236: plugin_loader.add_plugin_load_paths 237: end
Add the load paths used by support functions such as the info controller
# File vendor/rails/railties/lib/initializer.rb, line 230 230: def add_support_load_paths 231: end
Fires the user-supplied after_initialize block (Configuration#after_initialize)
# File vendor/rails/railties/lib/initializer.rb, line 465 465: def after_initialize 466: if @gems_dependencies_loaded 467: configuration.after_initialize_blocks.each do |block| 468: block.call 469: end 470: end 471: end
# File vendor/rails/railties/lib/initializer.rb, line 250 250: def check_gem_dependencies 251: unloaded_gems = @configuration.gems.reject { |g| g.loaded? } 252: if unloaded_gems.size > 0 253: @gems_dependencies_loaded = false 254: # don't print if the gems rake tasks are being run 255: unless $rails_gem_installer 256: puts %{These gems that this application depends on are missing:} 257: unloaded_gems.each do |gem| 258: puts " - #{gem.name}" 259: end 260: puts %{Run "rake gems:install" to install them.} 261: end 262: else 263: @gems_dependencies_loaded = true 264: end 265: end
Check for valid Ruby version This is done in an external file, so we can use it from the `rails` program as well without duplication.
# File vendor/rails/railties/lib/initializer.rb, line 164 164: def check_ruby_version 165: require 'ruby_version_check' 166: end
# File vendor/rails/railties/lib/initializer.rb, line 337 337: def initialize_cache 338: unless defined?(RAILS_CACHE) 339: silence_warnings { Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store(configuration.cache_store) } 340: end 341: end
This initialization routine does nothing unless :active_record is one of the frameworks to load (Configuration#frameworks). If it is, this sets the database configuration from Configuration#database_configuration and then establishes the connection.
# File vendor/rails/railties/lib/initializer.rb, line 330 330: def initialize_database 331: if configuration.frameworks.include?(:active_record) 332: ActiveRecord::Base.configurations = configuration.database_configuration 333: ActiveRecord::Base.establish_connection 334: end 335: end
Sets the dependency loading mechanism based on the value of Configuration#cache_classes.
# File vendor/rails/railties/lib/initializer.rb, line 415 415: def initialize_dependency_mechanism 416: Dependencies.mechanism = configuration.cache_classes ? :require : :load 417: end
For Ruby 1.8, this initialization sets $KCODE to ‘u’ to enable the multibyte safe operations. Plugin authors supporting other encodings should override this behaviour and set the relevant default_charset on ActionController::Base.
For Ruby 1.9, this does nothing. Specify the default encoding in the Ruby shebang line if you don‘t want UTF-8.
# File vendor/rails/railties/lib/initializer.rb, line 322 322: def initialize_encoding 323: $KCODE='u' if RUBY_VERSION < '1.9' 324: end
# File vendor/rails/railties/lib/initializer.rb, line 343 343: def initialize_framework_caches 344: if configuration.frameworks.include?(:action_controller) 345: ActionController::Base.cache_store ||= RAILS_CACHE 346: end 347: end
Sets the logger for Active Record, Action Controller, and Action Mailer (but only for those frameworks that are to be loaded). If the framework‘s logger is already set, it is not changed, otherwise it is set to use RAILS_DEFAULT_LOGGER.
# File vendor/rails/railties/lib/initializer.rb, line 386 386: def initialize_framework_logging 387: for framework in ([ :active_record, :action_controller, :action_mailer ] & configuration.frameworks) 388: framework.to_s.camelize.constantize.const_get("Base").logger ||= RAILS_DEFAULT_LOGGER 389: end 390: 391: RAILS_CACHE.logger ||= RAILS_DEFAULT_LOGGER 392: end
Initializes framework-specific settings for each of the loaded frameworks (Configuration#frameworks). The available settings map to the accessors on each of the corresponding Base classes.
# File vendor/rails/railties/lib/initializer.rb, line 451 451: def initialize_framework_settings 452: configuration.frameworks.each do |framework| 453: base_class = framework.to_s.camelize.constantize.const_get("Base") 454: 455: configuration.send(framework).each do |setting, value| 456: base_class.send("#{setting}=", value) 457: end 458: end 459: configuration.active_support.each do |setting, value| 460: ActiveSupport.send("#{setting}=", value) 461: end 462: end
Sets +ActionController::Base#view_paths+ and +ActionMailer::Base#template_root+ (but only for those frameworks that are to be loaded). If the framework‘s paths have already been set, it is not changed, otherwise it is set to use Configuration#view_path.
# File vendor/rails/railties/lib/initializer.rb, line 398 398: def initialize_framework_views 399: ActionMailer::Base.template_root ||= configuration.view_path if configuration.frameworks.include?(:action_mailer) 400: ActionController::Base.view_paths = [configuration.view_path] if configuration.frameworks.include?(:action_controller) && ActionController::Base.view_paths.empty? 401: end
If the RAILS_DEFAULT_LOGGER constant is already set, this initialization routine does nothing. If the constant is not set, and Configuration#logger is not nil, this also does nothing. Otherwise, a new logger instance is created at Configuration#log_path, with a default log level of Configuration#log_level.
If the log could not be created, the log will be set to output to STDERR, with a log level of WARN.
# File vendor/rails/railties/lib/initializer.rb, line 357 357: def initialize_logger 358: # if the environment has explicitly defined a logger, use it 359: return if defined?(RAILS_DEFAULT_LOGGER) 360: 361: unless logger = configuration.logger 362: begin 363: logger = ActiveSupport::BufferedLogger.new(configuration.log_path) 364: logger.level = ActiveSupport::BufferedLogger.const_get(configuration.log_level.to_s.upcase) 365: if configuration.environment == "production" 366: logger.auto_flushing = false 367: logger.set_non_blocking_io 368: end 369: rescue StandardError => e 370: logger = ActiveSupport::BufferedLogger.new(STDERR) 371: logger.level = ActiveSupport::BufferedLogger::WARN 372: logger.warn( 373: "Rails Error: Unable to access log file. Please ensure that #{configuration.log_path} exists and is chmod 0666. " + 374: "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed." 375: ) 376: end 377: end 378: 379: silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger } 380: end
If Action Controller is not one of the loaded frameworks (Configuration#frameworks) this does nothing. Otherwise, it loads the routing definitions and sets up loading module used to lazily load controllers (Configuration#controller_paths).
# File vendor/rails/railties/lib/initializer.rb, line 406 406: def initialize_routing 407: return unless configuration.frameworks.include?(:action_controller) 408: ActionController::Routing.controller_paths = configuration.controller_paths 409: ActionController::Routing::Routes.configuration_file = configuration.routes_configuration_file 410: ActionController::Routing::Routes.reload 411: end
# File vendor/rails/railties/lib/initializer.rb, line 425 425: def initialize_temporary_session_directory 426: if configuration.frameworks.include?(:action_controller) 427: session_path = "#{configuration.root_path}/tmp/sessions/" 428: ActionController::Base.session_options[:tmpdir] = File.exist?(session_path) ? session_path : Dir::tmpdir 429: end 430: end
Sets the default value for Time.zone, and turns on ActiveRecord::Base#time_zone_aware_attributes. If assigned value cannot be matched to a TimeZone, an exception will be raised.
# File vendor/rails/railties/lib/initializer.rb, line 434 434: def initialize_time_zone 435: if configuration.time_zone 436: zone_default = Time.send!(:get_zone, configuration.time_zone) 437: unless zone_default 438: raise %{Value assigned to config.time_zone not recognized. Run "rake -D time" for a list of tasks for finding appropriate time zone names.} 439: end 440: Time.zone_default = zone_default 441: if configuration.frameworks.include?(:active_record) 442: ActiveRecord::Base.time_zone_aware_attributes = true 443: ActiveRecord::Base.default_timezone = :utc 444: end 445: end 446: end
Loads support for "whiny nil" (noisy warnings when methods are invoked on nil values) if Configuration#whiny_nils is true.
# File vendor/rails/railties/lib/initializer.rb, line 421 421: def initialize_whiny_nils 422: require('active_support/whiny_nil') if configuration.whiny_nils 423: end
If Rails is vendored and RubyGems is available, install stub GemSpecs for Rails, Active Support, Active Record, Action Pack, Action Mailer, and Active Resource. This allows Gem plugins to depend on Rails even when the Gem version of Rails shouldn‘t be loaded.
# File vendor/rails/railties/lib/initializer.rb, line 172 172: def install_gem_spec_stubs 173: unless Rails.respond_to?(:vendor_rails?) 174: abort %{Your config/boot.rb is outdated: Run "rake rails:update".} 175: end 176: 177: if Rails.vendor_rails? 178: begin; require "rubygems"; rescue LoadError; return; end 179: 180: stubs = %w(rails activesupport activerecord actionpack actionmailer activeresource) 181: stubs.reject! { |s| Gem.loaded_specs.key?(s) } 182: 183: stubs.each do |stub| 184: Gem.loaded_specs[stub] = Gem::Specification.new do |s| 185: s.name = stub 186: s.version = Rails::VERSION::STRING 187: end 188: end 189: end 190: end
# File vendor/rails/railties/lib/initializer.rb, line 473 473: def load_application_initializers 474: if @gems_dependencies_loaded 475: Dir["#{configuration.root_path}/config/initializers/**/*.rb"].sort.each do |initializer| 476: load(initializer) 477: end 478: end 479: end
Loads the environment specified by Configuration#environment_path, which is typically one of development, test, or production.
# File vendor/rails/railties/lib/initializer.rb, line 293 293: def load_environment 294: silence_warnings do 295: return if @environment_loaded 296: @environment_loaded = true 297: 298: config = configuration 299: constants = self.class.constants 300: 301: eval(IO.read(configuration.environment_path), binding, configuration.environment_path) 302: 303: (self.class.constants - constants).each do |const| 304: Object.const_set(const, self.class.const_get(const)) 305: end 306: end 307: end
# File vendor/rails/railties/lib/initializer.rb, line 246 246: def load_gems 247: @configuration.gems.each(&:load) 248: end
# File vendor/rails/railties/lib/initializer.rb, line 309 309: def load_observers 310: if @gems_dependencies_loaded && configuration.frameworks.include?(:active_record) 311: ActiveRecord::Base.instantiate_observers 312: end 313: end
Loads all plugins in config.plugin_paths. plugin_paths defaults to vendor/plugins but may also be set to a list of paths, such as
config.plugin_paths = ["#{RAILS_ROOT}/lib/plugins", "#{RAILS_ROOT}/vendor/plugins"]
In the default implementation, as each plugin discovered in plugin_paths is initialized:
After all plugins are loaded, duplicates are removed from the load path. If an array of plugin names is specified in config.plugins, only those plugins will be loaded and they plugins will be loaded in that order. Otherwise, plugins are loaded in alphabetical order.
if config.plugins ends contains :all then the named plugins will be loaded in the given order and all other plugins will be loaded in alphabetical order
# File vendor/rails/railties/lib/initializer.rb, line 283 283: def load_plugins 284: plugin_loader.load_plugins 285: end
# File vendor/rails/railties/lib/initializer.rb, line 287 287: def plugin_loader 288: @plugin_loader ||= configuration.plugin_loader.new(self) 289: end
# File vendor/rails/railties/lib/initializer.rb, line 481 481: def prepare_dispatcher 482: require 'dispatcher' unless defined?(::Dispatcher) 483: Dispatcher.define_dispatcher_callbacks(configuration.cache_classes) 484: Dispatcher.new(RAILS_DEFAULT_LOGGER).send :run_callbacks, :prepare_dispatch 485: end
Sequentially step through all of the available initialization routines, in order (view execution order in source).
# File vendor/rails/railties/lib/initializer.rb, line 106 106: def process 107: Rails.configuration = configuration 108: 109: check_ruby_version 110: install_gem_spec_stubs 111: set_load_path 112: 113: require_frameworks 114: set_autoload_paths 115: add_gem_load_paths 116: add_plugin_load_paths 117: load_environment 118: 119: initialize_encoding 120: initialize_database 121: 122: initialize_cache 123: initialize_framework_caches 124: 125: initialize_logger 126: initialize_framework_logging 127: 128: initialize_framework_views 129: initialize_dependency_mechanism 130: initialize_whiny_nils 131: initialize_temporary_session_directory 132: initialize_time_zone 133: initialize_framework_settings 134: 135: add_support_load_paths 136: 137: load_gems 138: load_plugins 139: 140: # pick up any gems that plugins depend on 141: add_gem_load_paths 142: load_gems 143: check_gem_dependencies 144: 145: load_application_initializers 146: 147: # the framework is now fully initialized 148: after_initialize 149: 150: # Prepare dispatcher callbacks and run 'prepare' callbacks 151: prepare_dispatcher 152: 153: # Routing must be initialized after plugins to allow the former to extend the routes 154: initialize_routing 155: 156: # Observers are loaded after plugins in case Observers or observed models are modified by plugins. 157: 158: load_observers 159: end
Requires all frameworks specified by the Configuration#frameworks list. By default, all frameworks (Active Record, Active Support, Action Pack, Action Mailer, and Active Resource) are loaded.
# File vendor/rails/railties/lib/initializer.rb, line 222 222: def require_frameworks 223: configuration.frameworks.each { |framework| require(framework.to_s) } 224: rescue LoadError => e 225: # re-raise because Mongrel would swallow it 226: raise e.to_s 227: end
Set the paths from which Rails will automatically load source files, and the load_once paths.
# File vendor/rails/railties/lib/initializer.rb, line 202 202: def set_autoload_paths 203: Dependencies.load_paths = configuration.load_paths.uniq 204: Dependencies.load_once_paths = configuration.load_once_paths.uniq 205: 206: extra = Dependencies.load_once_paths - Dependencies.load_paths 207: unless extra.empty? 208: abort "load_once_paths must be a subset of the load_paths.\nExtra items in load_once_paths: \#{extra * ','}\n" 209: end 210: 211: # Freeze the arrays so future modifications will fail rather than do nothing mysteriously 212: configuration.load_once_paths.freeze 213: end
Set the $LOAD_PATH based on the value of Configuration#load_paths. Duplicates are removed.
# File vendor/rails/railties/lib/initializer.rb, line 194 194: def set_load_path 195: load_paths = configuration.load_paths + configuration.framework_paths 196: load_paths.reverse_each { |dir| $LOAD_PATH.unshift(dir) if File.directory?(dir) } 197: $LOAD_PATH.uniq! 198: end