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.

Methods
Attributes
[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.
Public Class methods
new(configuration)

Create a new Initializer instance that references the given Configuration instance.

     # File railties/lib/initializer.rb, line 119
119:     def initialize(configuration)
120:       @configuration = configuration
121:       @loaded_plugins = []
122:     end
run(command = :process, configuration = Configuration.new) {|configuration if block_given?| ...}

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.

     # 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
Public Instance methods
add_gem_load_paths()
     # File railties/lib/initializer.rb, line 296
296:     def add_gem_load_paths
297:       Rails::GemDependency.add_frozen_gem_path
298:       unless @configuration.gems.empty?
299:         require "rubygems"
300:         @configuration.gems.each { |gem| gem.add_load_paths }
301:       end
302:     end
add_plugin_load_paths()

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).

     # File railties/lib/initializer.rb, line 292
292:     def add_plugin_load_paths
293:       plugin_loader.add_plugin_load_paths
294:     end
add_support_load_paths()

Add the load paths used by support functions such as the info controller

     # File railties/lib/initializer.rb, line 287
287:     def add_support_load_paths
288:     end
after_initialize()

Fires the user-supplied after_initialize block (Configuration#after_initialize)

     # File railties/lib/initializer.rb, line 591
591:     def after_initialize
592:       if gems_dependencies_loaded
593:         configuration.after_initialize_blocks.each do |block|
594:           block.call
595:         end
596:       end
597:     end
check_gem_dependencies()
     # File railties/lib/initializer.rb, line 310
310:     def check_gem_dependencies
311:       unloaded_gems = @configuration.gems.reject { |g| g.loaded? }
312:       if unloaded_gems.size > 0
313:         @gems_dependencies_loaded = false
314:         # don't print if the gems rake tasks are being run
315:         unless $gems_rake_task
316:           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"
317:         end
318:       else
319:         @gems_dependencies_loaded = true
320:       end
321:     end
check_ruby_version()

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 railties/lib/initializer.rb, line 207
207:     def check_ruby_version
208:       require 'ruby_version_check'
209:     end
disable_dependency_loading()
     # File railties/lib/initializer.rb, line 614
614:     def disable_dependency_loading
615:       if configuration.cache_classes && !configuration.dependency_loading
616:         ActiveSupport::Dependencies.unhook!
617:       end
618:     end
initialize_cache()
     # File railties/lib/initializer.rb, line 435
435:     def initialize_cache
436:       unless defined?(RAILS_CACHE)
437:         silence_warnings { Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store(configuration.cache_store) }
438: 
439:         if RAILS_CACHE.respond_to?(:middleware)
440:           # Insert middleware to setup and teardown local cache for each request
441:           configuration.middleware.insert_after("ActionController::Failsafe""ActionController::Failsafe", RAILS_CACHE.middleware)
442:         end
443:       end
444:     end
initialize_database()

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 railties/lib/initializer.rb, line 416
416:     def initialize_database
417:       if configuration.frameworks.include?(:active_record)
418:         ActiveRecord::Base.configurations = configuration.database_configuration
419:         ActiveRecord::Base.establish_connection
420:       end
421:     end
initialize_database_middleware()
     # File railties/lib/initializer.rb, line 423
423:     def initialize_database_middleware
424:       if configuration.frameworks.include?(:active_record)
425:         if ActionController::Base.session_store == ActiveRecord::SessionStore
426:           configuration.middleware.insert_before "ActiveRecord::SessionStore""ActiveRecord::SessionStore", ActiveRecord::ConnectionAdapters::ConnectionManagement
427:           configuration.middleware.insert_before "ActiveRecord::SessionStore""ActiveRecord::SessionStore", ActiveRecord::QueryCache
428:         else
429:           configuration.middleware.use ActiveRecord::ConnectionAdapters::ConnectionManagement
430:           configuration.middleware.use ActiveRecord::QueryCache
431:         end
432:       end
433:     end
initialize_dependency_mechanism()

Sets the dependency loading mechanism based on the value of Configuration#cache_classes.

     # File railties/lib/initializer.rb, line 522
522:     def initialize_dependency_mechanism
523:       ActiveSupport::Dependencies.mechanism = configuration.cache_classes ? :require : :load
524:     end
initialize_encoding()

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 railties/lib/initializer.rb, line 408
408:     def initialize_encoding
409:       $KCODE='u' if RUBY_VERSION < '1.9'
410:     end
initialize_framework_caches()
     # File railties/lib/initializer.rb, line 446
446:     def initialize_framework_caches
447:       if configuration.frameworks.include?(:action_controller)
448:         ActionController::Base.cache_store ||= RAILS_CACHE
449:       end
450:     end
initialize_framework_logging()

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 railties/lib/initializer.rb, line 488
488:     def initialize_framework_logging
489:       for framework in ([ :active_record, :action_controller, :action_mailer ] & configuration.frameworks)
490:         framework.to_s.camelize.constantize.const_get("Base").logger ||= Rails.logger
491:       end
492: 
493:       ActiveSupport::Dependencies.logger ||= Rails.logger
494:       Rails.cache.logger ||= Rails.logger
495:     end
initialize_framework_settings()

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 railties/lib/initializer.rb, line 577
577:     def initialize_framework_settings
578:       configuration.frameworks.each do |framework|
579:         base_class = framework.to_s.camelize.constantize.const_get("Base")
580: 
581:         configuration.send(framework).each do |setting, value|
582:           base_class.send("#{setting}=", value)
583:         end
584:       end
585:       configuration.active_support.each do |setting, value|
586:         ActiveSupport.send("#{setting}=", value)
587:       end
588:     end
initialize_framework_views()

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 railties/lib/initializer.rb, line 501
501:     def initialize_framework_views
502:       if configuration.frameworks.include?(:action_view)
503:         view_path = ActionView::PathSet.type_cast(configuration.view_path)
504:         ActionMailer::Base.template_root  = view_path if configuration.frameworks.include?(:action_mailer) && ActionMailer::Base.view_paths.blank?
505:         ActionController::Base.view_paths = view_path if configuration.frameworks.include?(:action_controller) && ActionController::Base.view_paths.blank?
506:       end
507:     end
initialize_i18n()

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.

     # File railties/lib/initializer.rb, line 555
555:     def initialize_i18n
556:       configuration.i18n.each do |setting, value|
557:         if setting == :load_path
558:           I18n.load_path += value
559:         else
560:           I18n.send("#{setting}=", value)
561:         end
562:       end
563:     end
initialize_logger()

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 railties/lib/initializer.rb, line 460
460:     def initialize_logger
461:       # if the environment has explicitly defined a logger, use it
462:       return if Rails.logger
463: 
464:       unless logger = configuration.logger
465:         begin
466:           logger = ActiveSupport::BufferedLogger.new(configuration.log_path)
467:           logger.level = ActiveSupport::BufferedLogger.const_get(configuration.log_level.to_s.upcase)
468:           if configuration.environment == "production"
469:             logger.auto_flushing = false
470:           end
471:         rescue StandardError => e
472:           logger = ActiveSupport::BufferedLogger.new(STDERR)
473:           logger.level = ActiveSupport::BufferedLogger::WARN
474:           logger.warn(
475:             "Rails Error: Unable to access log file. Please ensure that #{configuration.log_path} exists and is chmod 0666. " +
476:             "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
477:           )
478:         end
479:       end
480: 
481:       silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }
482:     end
initialize_metal()
     # File railties/lib/initializer.rb, line 565
565:     def initialize_metal
566:       Rails::Rack::Metal.requested_metals = configuration.metals
567:       Rails::Rack::Metal.metal_paths += plugin_loader.engine_metal_paths
568: 
569:       configuration.middleware.insert_before(
570:         "ActionController::RewindableInput""ActionController::RewindableInput",
571:         Rails::Rack::Metal, :if => Rails::Rack::Metal.metals.any?)
572:     end
initialize_routing()

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 railties/lib/initializer.rb, line 512
512:     def initialize_routing
513:       return unless configuration.frameworks.include?(:action_controller)
514: 
515:       ActionController::Routing.controller_paths += configuration.controller_paths
516:       ActionController::Routing::Routes.add_configuration_file(configuration.routes_configuration_file)
517:       ActionController::Routing::Routes.reload!
518:     end
initialize_time_zone()

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 railties/lib/initializer.rb, line 534
534:     def initialize_time_zone
535:       if configuration.time_zone
536:         zone_default = Time.__send__(:get_zone, configuration.time_zone)
537: 
538:         unless zone_default
539:           raise \
540:             'Value assigned to config.time_zone not recognized.' +
541:             'Run "rake -D time" for a list of tasks for finding appropriate time zone names.'
542:         end
543: 
544:         Time.zone_default = zone_default
545: 
546:         if configuration.frameworks.include?(:active_record)
547:           ActiveRecord::Base.time_zone_aware_attributes = true
548:           ActiveRecord::Base.default_timezone = :utc
549:         end
550:       end
551:     end
initialize_whiny_nils()

Loads support for "whiny nil" (noisy warnings when methods are invoked on nil values) if Configuration#whiny_nils is true.

     # File railties/lib/initializer.rb, line 528
528:     def initialize_whiny_nils
529:       require('active_support/whiny_nil') if configuration.whiny_nils
530:     end
install_gem_spec_stubs()

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 railties/lib/initializer.rb, line 215
215:     def install_gem_spec_stubs
216:       unless Rails.respond_to?(:vendor_rails?)
217:         abort %{Your config/boot.rb is outdated: Run "rake rails:update".}
218:       end
219: 
220:       if Rails.vendor_rails?
221:         begin; require "rubygems"; rescue LoadError; return; end
222: 
223:         stubs = %w(rails activesupport activerecord actionpack actionmailer activeresource)
224:         stubs.reject! { |s| Gem.loaded_specs.key?(s) }
225: 
226:         stubs.each do |stub|
227:           Gem.loaded_specs[stub] = Gem::Specification.new do |s|
228:             s.name = stub
229:             s.version = Rails::VERSION::STRING
230:             s.loaded_from = ""
231:           end
232:         end
233:       end
234:     end
load_application_classes()

Eager load application classes

     # File railties/lib/initializer.rb, line 389
389:     def load_application_classes
390:       return if $rails_rake_task
391:       if configuration.cache_classes
392:         configuration.eager_load_paths.each do |load_path|
393:           matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/
394:           Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
395:             require_dependency file.sub(matcher, '\1')
396:           end
397:         end
398:       end
399:     end
load_application_initializers()
     # File railties/lib/initializer.rb, line 599
599:     def load_application_initializers
600:       if gems_dependencies_loaded
601:         Dir["#{configuration.root_path}/config/initializers/**/*.rb"].sort.each do |initializer|
602:           load(initializer)
603:         end
604:       end
605:     end
load_environment()

Loads the environment specified by Configuration#environment_path, which is typically one of development, test, or production.

     # File railties/lib/initializer.rb, line 359
359:     def load_environment
360:       silence_warnings do
361:         return if @environment_loaded
362:         @environment_loaded = true
363: 
364:         config = configuration
365:         constants = self.class.constants
366: 
367:         eval(IO.read(configuration.environment_path), binding, configuration.environment_path)
368: 
369:         (self.class.constants - constants).each do |const|
370:           Object.const_set(const, self.class.const_get(const))
371:         end
372:       end
373:     end
load_gems()
     # File railties/lib/initializer.rb, line 304
304:     def load_gems
305:       unless $gems_build_rake_task
306:         @configuration.gems.each { |gem| gem.load }
307:       end
308:     end
load_observers()
     # File railties/lib/initializer.rb, line 375
375:     def load_observers
376:       if gems_dependencies_loaded && configuration.frameworks.include?(:active_record)
377:         ActiveRecord::Base.instantiate_observers
378:       end
379:     end
load_plugins()

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

     # File railties/lib/initializer.rb, line 349
349:     def load_plugins
350:       plugin_loader.load_plugins
351:     end
load_view_paths()
     # File railties/lib/initializer.rb, line 381
381:     def load_view_paths
382:       if configuration.frameworks.include?(:action_view)
383:         ActionController::Base.view_paths.load! if configuration.frameworks.include?(:action_controller)
384:         ActionMailer::Base.view_paths.load! if configuration.frameworks.include?(:action_mailer)
385:       end
386:     end
plugin_loader()
     # File railties/lib/initializer.rb, line 353
353:     def plugin_loader
354:       @plugin_loader ||= configuration.plugin_loader.new(self)
355:     end
preload_frameworks()

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.

     # File railties/lib/initializer.rb, line 276
276:     def preload_frameworks
277:       if configuration.preload_frameworks
278:         configuration.frameworks.each do |framework|
279:           # String#classify and #constantize aren't available yet.
280:           toplevel = Object.const_get(framework.to_s.gsub(/(?:^|_)(.)/) { $1.upcase })
281:           toplevel.load_all! if toplevel.respond_to?(:load_all!)
282:         end
283:       end
284:     end
prepare_dispatcher()
     # File railties/lib/initializer.rb, line 607
607:     def prepare_dispatcher
608:       return unless configuration.frameworks.include?(:action_controller)
609:       require 'dispatcher' unless defined?(::Dispatcher)
610:       Dispatcher.define_dispatcher_callbacks(configuration.cache_classes)
611:       Dispatcher.run_prepare_callbacks
612:     end
process()

Sequentially step through all of the available initialization routines, in order (view execution order in 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:       load_gems
163:       load_plugins
164: 
165:       # pick up any gems that plugins depend on
166:       add_gem_load_paths
167:       load_gems
168:       check_gem_dependencies
169: 
170:       # bail out if gems are missing - note that check_gem_dependencies will have
171:       # already called abort() unless $gems_rake_task is set
172:       return unless gems_dependencies_loaded
173: 
174:       load_application_initializers
175: 
176:       # the framework is now fully initialized
177:       after_initialize
178: 
179:       # Setup database middleware after initializers have run
180:       initialize_database_middleware
181: 
182:       # Prepare dispatcher callbacks and run 'prepare' callbacks
183:       prepare_dispatcher
184: 
185:       # Routing must be initialized after plugins to allow the former to extend the routes
186:       initialize_routing
187: 
188:       # Observers are loaded after plugins in case Observers or observed models are modified by plugins.
189:       load_observers
190: 
191:       # Load view path cache
192:       load_view_paths
193: 
194:       # Load application classes
195:       load_application_classes
196: 
197:       # Disable dependency loading during request cycle
198:       disable_dependency_loading
199: 
200:       # Flag initialized
201:       Rails.initialized = true
202:     end
require_frameworks()

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 railties/lib/initializer.rb, line 266
266:     def require_frameworks
267:       configuration.frameworks.each { |framework| require(framework.to_s) }
268:     rescue LoadError => e
269:       # Re-raise as RuntimeError because Mongrel would swallow LoadError.
270:       raise e.to_s
271:     end
set_autoload_paths()

Set the paths from which Rails will automatically load source files, and the load_once paths.

     # File railties/lib/initializer.rb, line 246
246:     def set_autoload_paths
247:       ActiveSupport::Dependencies.load_paths = configuration.load_paths.uniq
248:       ActiveSupport::Dependencies.load_once_paths = configuration.load_once_paths.uniq
249: 
250:       extra = ActiveSupport::Dependencies.load_once_paths - ActiveSupport::Dependencies.load_paths
251:       unless extra.empty?
252:         abort "load_once_paths must be a subset of the load_paths.\nExtra items in load_once_paths: \#{extra * ','}\n"
253:       end
254: 
255:       # Freeze the arrays so future modifications will fail rather than do nothing mysteriously
256:       configuration.load_once_paths.freeze
257:     end
set_load_path()

Set the $LOAD_PATH based on the value of Configuration#load_paths. Duplicates are removed.

     # File railties/lib/initializer.rb, line 238
238:     def set_load_path
239:       load_paths = configuration.load_paths + configuration.framework_paths
240:       load_paths.reverse_each { |dir| $LOAD_PATH.unshift(dir) if File.directory?(dir) }
241:       $LOAD_PATH.uniq!
242:     end