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.
- add_gem_load_paths
- add_plugin_load_paths
- add_support_load_paths
- after_initialize
- check_for_unbuilt_gems
- check_gem_dependencies
- check_ruby_version
- disable_dependency_loading
- initialize_cache
- initialize_database
- initialize_database_middleware
- initialize_dependency_mechanism
- initialize_encoding
- initialize_framework_caches
- initialize_framework_logging
- initialize_framework_settings
- initialize_framework_views
- initialize_i18n
- initialize_logger
- initialize_metal
- initialize_routing
- initialize_time_zone
- initialize_whiny_nils
- install_gem_spec_stubs
- load_application_classes
- load_application_initializers
- load_environment
- load_gems
- load_observers
- load_plugins
- load_view_paths
- new
- plugin_loader
- preload_frameworks
- prepare_dispatcher
- process
- require_frameworks
- run
- set_autoload_paths
- set_load_path
[R] | configuration | The Configuration instance used by this Initializer instance. |
[R] | gems_dependencies_loaded | Whether or not all the gem dependencies have been met |
[R] | loaded_plugins | The set of loaded plugins. |
Create a new Initializer instance that references the given Configuration instance.
[ show source ]
# File railties/lib/initializer.rb, line 119 119: def initialize(configuration) 120: @configuration = configuration 121: @loaded_plugins = [] 122: 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 incurring the overhead of completely loading the entire environment.
[ show source ]
# File railties/lib/initializer.rb, line 110 110: def self.run(command = :process, configuration = Configuration.new) 111: yield configuration if block_given? 112: initializer = new configuration 113: initializer.send(command) 114: initializer 115: end
[ show source ]
# File railties/lib/initializer.rb, line 298 298: def add_gem_load_paths 299: Rails::GemDependency.add_frozen_gem_path 300: unless @configuration.gems.empty? 301: require "rubygems" 302: @configuration.gems.each { |gem| gem.add_load_paths } 303: end 304: 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 ActiveSupport::Dependencies).
[ show source ]
# File railties/lib/initializer.rb, line 294 294: def add_plugin_load_paths 295: plugin_loader.add_plugin_load_paths 296: end
Add the load paths used by support functions such as the info controller
[ show source ]
# File railties/lib/initializer.rb, line 289 289: def add_support_load_paths 290: end
Fires the user-supplied after_initialize block (Configuration#after_initialize)
[ show source ]
# File railties/lib/initializer.rb, line 614 614: def after_initialize 615: if gems_dependencies_loaded 616: configuration.after_initialize_blocks.each do |block| 617: block.call 618: end 619: end 620: end
[ show source ]
# File railties/lib/initializer.rb, line 312 312: def check_for_unbuilt_gems 313: unbuilt_gems = @configuration.gems.select(&:frozen?).reject(&:built?) 314: if unbuilt_gems.size > 0 315: # don't print if the gems:build rake tasks are being run 316: unless $gems_build_rake_task 317: abort "The following gems have native components that need to be built\n\#{unbuilt_gems.map { |gem| \"\#{gem.name} \#{gem.requirement}\" } * \"\\n \"}\n\nYou're running:\nruby \#{Gem.ruby_version} at \#{Gem.ruby}\nrubygems \#{Gem::RubyGemsVersion} at \#{Gem.path * ', '}\n\nRun `rake gems:build` to build the unbuilt gems.\n" 318: end 319: end 320: end
[ show source ]
# File railties/lib/initializer.rb, line 332 332: def check_gem_dependencies 333: unloaded_gems = @configuration.gems.reject { |g| g.loaded? } 334: if unloaded_gems.size > 0 335: @gems_dependencies_loaded = false 336: # don't print if the gems rake tasks are being run 337: unless $gems_rake_task 338: abort "Missing these required gems:\n\#{unloaded_gems.map { |gem| \"\#{gem.name} \#{gem.requirement}\" } * \"\\n \"}\n\nYou're running:\nruby \#{Gem.ruby_version} at \#{Gem.ruby}\nrubygems \#{Gem::RubyGemsVersion} at \#{Gem.path * ', '}\n\nRun `rake gems:install` to install the missing gems.\n" 339: end 340: else 341: @gems_dependencies_loaded = true 342: end 343: 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.
[ show source ]
# File railties/lib/initializer.rb, line 209 209: def check_ruby_version 210: require 'ruby_version_check' 211: end
[ show source ]
# File railties/lib/initializer.rb, line 637 637: def disable_dependency_loading 638: if configuration.cache_classes && !configuration.dependency_loading 639: ActiveSupport::Dependencies.unhook! 640: end 641: end
[ show source ]
# File railties/lib/initializer.rb, line 458 458: def initialize_cache 459: unless defined?(RAILS_CACHE) 460: silence_warnings { Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store(configuration.cache_store) } 461: 462: if RAILS_CACHE.respond_to?(:middleware) 463: # Insert middleware to setup and teardown local cache for each request 464: configuration.middleware.insert_after("ActionController::Failsafe""ActionController::Failsafe", RAILS_CACHE.middleware) 465: end 466: end 467: 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.
[ show source ]
# File railties/lib/initializer.rb, line 438 438: def initialize_database 439: if configuration.frameworks.include?(:active_record) 440: ActiveRecord::Base.configurations = configuration.database_configuration 441: ActiveRecord::Base.establish_connection 442: end 443: end
[ show source ]
# File railties/lib/initializer.rb, line 445 445: def initialize_database_middleware 446: if configuration.frameworks.include?(:active_record) 447: if configuration.frameworks.include?(:action_controller) && 448: ActionController::Base.session_store.name == 'ActiveRecord::SessionStore' 449: configuration.middleware.insert_before "ActiveRecord::SessionStore""ActiveRecord::SessionStore", ActiveRecord::ConnectionAdapters::ConnectionManagement 450: configuration.middleware.insert_before "ActiveRecord::SessionStore""ActiveRecord::SessionStore", ActiveRecord::QueryCache 451: else 452: configuration.middleware.use ActiveRecord::ConnectionAdapters::ConnectionManagement 453: configuration.middleware.use ActiveRecord::QueryCache 454: end 455: end 456: end
Sets the dependency loading mechanism based on the value of Configuration#cache_classes.
[ show source ]
# File railties/lib/initializer.rb, line 545 545: def initialize_dependency_mechanism 546: ActiveSupport::Dependencies.mechanism = configuration.cache_classes ? :require : :load 547: 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.
[ show source ]
# File railties/lib/initializer.rb, line 430 430: def initialize_encoding 431: $KCODE='u' if RUBY_VERSION < '1.9' 432: end
[ show source ]
# File railties/lib/initializer.rb, line 469 469: def initialize_framework_caches 470: if configuration.frameworks.include?(:action_controller) 471: ActionController::Base.cache_store ||= RAILS_CACHE 472: end 473: 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.
[ show source ]
# File railties/lib/initializer.rb, line 511 511: def initialize_framework_logging 512: for framework in ([ :active_record, :action_controller, :action_mailer ] & configuration.frameworks) 513: framework.to_s.camelize.constantize.const_get("Base").logger ||= Rails.logger 514: end 515: 516: ActiveSupport::Dependencies.logger ||= Rails.logger 517: Rails.cache.logger ||= Rails.logger 518: 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.
[ show source ]
# File railties/lib/initializer.rb, line 600 600: def initialize_framework_settings 601: configuration.frameworks.each do |framework| 602: base_class = framework.to_s.camelize.constantize.const_get("Base") 603: 604: configuration.send(framework).each do |setting, value| 605: base_class.send("#{setting}=", value) 606: end 607: end 608: configuration.active_support.each do |setting, value| 609: ActiveSupport.send("#{setting}=", value) 610: end 611: 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.
[ show source ]
# File railties/lib/initializer.rb, line 524 524: def initialize_framework_views 525: if configuration.frameworks.include?(:action_view) 526: view_path = ActionView::PathSet.type_cast(configuration.view_path) 527: ActionMailer::Base.template_root = view_path if configuration.frameworks.include?(:action_mailer) && ActionMailer::Base.view_paths.blank? 528: ActionController::Base.view_paths = view_path if configuration.frameworks.include?(:action_controller) && ActionController::Base.view_paths.blank? 529: end 530: end
Set the i18n configuration from config.i18n but special-case for the load_path which should be appended to what‘s already set instead of overwritten.
[ show source ]
# File railties/lib/initializer.rb, line 578 578: def initialize_i18n 579: configuration.i18n.each do |setting, value| 580: if setting == :load_path 581: I18n.load_path += value 582: else 583: I18n.send("#{setting}=", value) 584: end 585: end 586: 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.
[ show source ]
# File railties/lib/initializer.rb, line 483 483: def initialize_logger 484: # if the environment has explicitly defined a logger, use it 485: return if Rails.logger 486: 487: unless logger = configuration.logger 488: begin 489: logger = ActiveSupport::BufferedLogger.new(configuration.log_path) 490: logger.level = ActiveSupport::BufferedLogger.const_get(configuration.log_level.to_s.upcase) 491: if configuration.environment == "production" 492: logger.auto_flushing = false 493: end 494: rescue StandardError => e 495: logger = ActiveSupport::BufferedLogger.new(STDERR) 496: logger.level = ActiveSupport::BufferedLogger::WARN 497: logger.warn( 498: "Rails Error: Unable to access log file. Please ensure that #{configuration.log_path} exists and is chmod 0666. " + 499: "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed." 500: ) 501: end 502: end 503: 504: silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger } 505: end
[ show source ]
# File railties/lib/initializer.rb, line 588 588: def initialize_metal 589: Rails::Rack::Metal.requested_metals = configuration.metals 590: Rails::Rack::Metal.metal_paths += plugin_loader.engine_metal_paths 591: 592: configuration.middleware.insert_before( 593: "ActionController::ParamsParser""ActionController::ParamsParser", 594: Rails::Rack::Metal, :if => Rails::Rack::Metal.metals.any?) 595: 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).
[ show source ]
# File railties/lib/initializer.rb, line 535 535: def initialize_routing 536: return unless configuration.frameworks.include?(:action_controller) 537: 538: ActionController::Routing.controller_paths += configuration.controller_paths 539: ActionController::Routing::Routes.add_configuration_file(configuration.routes_configuration_file) 540: ActionController::Routing::Routes.reload! 541: 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.
[ show source ]
# File railties/lib/initializer.rb, line 557 557: def initialize_time_zone 558: if configuration.time_zone 559: zone_default = Time.__send__(:get_zone, configuration.time_zone) 560: 561: unless zone_default 562: raise \ 563: 'Value assigned to config.time_zone not recognized.' + 564: 'Run "rake -D time" for a list of tasks for finding appropriate time zone names.' 565: end 566: 567: Time.zone_default = zone_default 568: 569: if configuration.frameworks.include?(:active_record) 570: ActiveRecord::Base.time_zone_aware_attributes = true 571: ActiveRecord::Base.default_timezone = :utc 572: end 573: end 574: end
Loads support for "whiny nil" (noisy warnings when methods are invoked on nil values) if Configuration#whiny_nils is true.
[ show source ]
# File railties/lib/initializer.rb, line 551 551: def initialize_whiny_nils 552: require('active_support/whiny_nil') if configuration.whiny_nils 553: 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.
[ show source ]
# File railties/lib/initializer.rb, line 217 217: def install_gem_spec_stubs 218: unless Rails.respond_to?(:vendor_rails?) 219: abort %{Your config/boot.rb is outdated: Run "rake rails:update".} 220: end 221: 222: if Rails.vendor_rails? 223: begin; require "rubygems"; rescue LoadError; return; end 224: 225: stubs = %w(rails activesupport activerecord actionpack actionmailer activeresource) 226: stubs.reject! { |s| Gem.loaded_specs.key?(s) } 227: 228: stubs.each do |stub| 229: Gem.loaded_specs[stub] = Gem::Specification.new do |s| 230: s.name = stub 231: s.version = Rails::VERSION::STRING 232: s.loaded_from = "" 233: end 234: end 235: end 236: end
Eager load application classes
[ show source ]
# File railties/lib/initializer.rb, line 411 411: def load_application_classes 412: return if $rails_rake_task && configuration.dependency_loading 413: if configuration.cache_classes 414: configuration.eager_load_paths.each do |load_path| 415: matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/ 416: Dir.glob("#{load_path}/**/*.rb").sort.each do |file| 417: require_dependency file.sub(matcher, '\1') 418: end 419: end 420: end 421: end
[ show source ]
# File railties/lib/initializer.rb, line 622 622: def load_application_initializers 623: if gems_dependencies_loaded 624: Dir["#{configuration.root_path}/config/initializers/**/*.rb"].sort.each do |initializer| 625: load(initializer) 626: end 627: end 628: end
Loads the environment specified by Configuration#environment_path, which is typically one of development, test, or production.
[ show source ]
# File railties/lib/initializer.rb, line 381 381: def load_environment 382: silence_warnings do 383: return if @environment_loaded 384: @environment_loaded = true 385: 386: config = configuration 387: constants = self.class.constants 388: 389: eval(IO.read(configuration.environment_path), binding, configuration.environment_path) 390: 391: (self.class.constants - constants).each do |const| 392: Object.const_set(const, self.class.const_get(const)) 393: end 394: end 395: end
[ show source ]
# File railties/lib/initializer.rb, line 306 306: def load_gems 307: unless $gems_rake_task 308: @configuration.gems.each { |gem| gem.load } 309: end 310: end
[ show source ]
# File railties/lib/initializer.rb, line 397 397: def load_observers 398: if gems_dependencies_loaded && configuration.frameworks.include?(:active_record) 399: ActiveRecord::Base.instantiate_observers 400: end 401: 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:
- its lib directory, if present, is added to the load path (immediately after the applications lib directory)
- init.rb is evaluated, if present
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
[ show source ]
# File railties/lib/initializer.rb, line 371 371: def load_plugins 372: plugin_loader.load_plugins 373: end
[ show source ]
# File railties/lib/initializer.rb, line 403 403: def load_view_paths 404: if configuration.frameworks.include?(:action_view) 405: ActionController::Base.view_paths.load! if configuration.frameworks.include?(:action_controller) 406: ActionMailer::Base.view_paths.load! if configuration.frameworks.include?(:action_mailer) 407: end 408: end
[ show source ]
# File railties/lib/initializer.rb, line 375 375: def plugin_loader 376: @plugin_loader ||= configuration.plugin_loader.new(self) 377: end
Preload all frameworks specified by the Configuration#frameworks. Used by Passenger to ensure everything‘s loaded before forking and to avoid autoload race conditions in JRuby.
[ show source ]
# File railties/lib/initializer.rb, line 278 278: def preload_frameworks 279: if configuration.preload_frameworks 280: configuration.frameworks.each do |framework| 281: # String#classify and #constantize aren't available yet. 282: toplevel = Object.const_get(framework.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }) 283: toplevel.load_all! if toplevel.respond_to?(:load_all!) 284: end 285: end 286: end
[ show source ]
# File railties/lib/initializer.rb, line 630 630: def prepare_dispatcher 631: return unless configuration.frameworks.include?(:action_controller) 632: require 'dispatcher' unless defined?(::Dispatcher) 633: Dispatcher.define_dispatcher_callbacks(configuration.cache_classes) 634: Dispatcher.run_prepare_callbacks 635: end
Sequentially step through all of the available initialization routines, in order (view execution order in source).
[ show source ]
# File railties/lib/initializer.rb, line 126 126: def process 127: Rails.configuration = configuration 128: 129: check_ruby_version 130: install_gem_spec_stubs 131: set_load_path 132: add_gem_load_paths 133: 134: require_frameworks 135: set_autoload_paths 136: add_plugin_load_paths 137: load_environment 138: preload_frameworks 139: 140: initialize_encoding 141: initialize_database 142: 143: initialize_cache 144: initialize_framework_caches 145: 146: initialize_logger 147: initialize_framework_logging 148: 149: initialize_dependency_mechanism 150: initialize_whiny_nils 151: 152: initialize_time_zone 153: initialize_i18n 154: 155: initialize_framework_settings 156: initialize_framework_views 157: 158: initialize_metal 159: 160: add_support_load_paths 161: 162: check_for_unbuilt_gems 163: 164: load_gems 165: load_plugins 166: 167: # pick up any gems that plugins depend on 168: add_gem_load_paths 169: load_gems 170: check_gem_dependencies 171: 172: # bail out if gems are missing - note that check_gem_dependencies will have 173: # already called abort() unless $gems_rake_task is set 174: return unless gems_dependencies_loaded 175: 176: load_application_initializers 177: 178: # the framework is now fully initialized 179: after_initialize 180: 181: # Setup database middleware after initializers have run 182: initialize_database_middleware 183: 184: # Prepare dispatcher callbacks and run 'prepare' callbacks 185: prepare_dispatcher 186: 187: # Routing must be initialized after plugins to allow the former to extend the routes 188: initialize_routing 189: 190: # Observers are loaded after plugins in case Observers or observed models are modified by plugins. 191: load_observers 192: 193: # Load view path cache 194: load_view_paths 195: 196: # Load application classes 197: load_application_classes 198: 199: # Disable dependency loading during request cycle 200: disable_dependency_loading 201: 202: # Flag initialized 203: Rails.initialized = true 204: 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.
[ show source ]
# File railties/lib/initializer.rb, line 268 268: def require_frameworks 269: configuration.frameworks.each { |framework| require(framework.to_s) } 270: rescue LoadError => e 271: # Re-raise as RuntimeError because Mongrel would swallow LoadError. 272: raise e.to_s 273: end
Set the paths from which Rails will automatically load source files, and the load_once paths.
[ show source ]
# File railties/lib/initializer.rb, line 248 248: def set_autoload_paths 249: ActiveSupport::Dependencies.autoload_paths = configuration.autoload_paths.uniq 250: ActiveSupport::Dependencies.autoload_once_paths = configuration.autoload_once_paths.uniq 251: 252: extra = ActiveSupport::Dependencies.autoload_once_paths - ActiveSupport::Dependencies.autoload_paths 253: unless extra.empty? 254: abort "autoload_once_paths must be a subset of the autoload_paths.\nExtra items in autoload_once_paths: \#{extra * ','}\n" 255: end 256: 257: # Freeze the arrays so future modifications will fail rather than do nothing mysteriously 258: configuration.autoload_once_paths.freeze 259: end
Set the $LOAD_PATH based on the value of Configuration#autoload_paths. Duplicates are removed.
[ show source ]
# File railties/lib/initializer.rb, line 240 240: def set_load_path 241: load_paths = configuration.autoload_paths + configuration.framework_paths 242: load_paths.reverse_each { |dir| $LOAD_PATH.unshift(dir) if File.directory?(dir) } 243: $LOAD_PATH.uniq! 244: end