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 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
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 294
294:     def add_plugin_load_paths
295:       plugin_loader.add_plugin_load_paths
296:     end
add_support_load_paths()

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

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

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

     # 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
check_for_unbuilt_gems()
     # 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
check_gem_dependencies()
     # 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_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 209
209:     def check_ruby_version
210:       require 'ruby_version_check'
211:     end
disable_dependency_loading()
     # 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
initialize_cache()
     # 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
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 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
initialize_database_middleware()
     # 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
initialize_dependency_mechanism()

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

     # File railties/lib/initializer.rb, line 545
545:     def initialize_dependency_mechanism
546:       ActiveSupport::Dependencies.mechanism = configuration.cache_classes ? :require : :load
547:     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 430
430:     def initialize_encoding
431:       $KCODE='u' if RUBY_VERSION < '1.9'
432:     end
initialize_framework_caches()
     # 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
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 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
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 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
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 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
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 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
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 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
initialize_metal()
     # 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
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 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
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 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
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 551
551:     def initialize_whiny_nils
552:       require('active_support/whiny_nil') if configuration.whiny_nils
553:     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 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
load_application_classes()

Eager load application classes

     # File railties/lib/initializer.rb, line 411
411:     def load_application_classes
412:       return if $rails_rake_task
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
load_application_initializers()
     # 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
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 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
load_gems()
     # 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
load_observers()
     # 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
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 371
371:     def load_plugins
372:       plugin_loader.load_plugins
373:     end
load_view_paths()
     # 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
plugin_loader()
     # File railties/lib/initializer.rb, line 375
375:     def plugin_loader
376:       @plugin_loader ||= configuration.plugin_loader.new(self)
377:     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 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
prepare_dispatcher()
     # 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
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:       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
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 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_autoload_paths()

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

     # File railties/lib/initializer.rb, line 248
248:     def set_autoload_paths
249:       ActiveSupport::Dependencies.load_paths = configuration.load_paths.uniq
250:       ActiveSupport::Dependencies.load_once_paths = configuration.load_once_paths.uniq
251: 
252:       extra = ActiveSupport::Dependencies.load_once_paths - ActiveSupport::Dependencies.load_paths
253:       unless extra.empty?
254:         abort "load_once_paths must be a subset of the load_paths.\nExtra items in load_once_paths: \#{extra * ','}\n"
255:       end
256: 
257:       # Freeze the arrays so future modifications will fail rather than do nothing mysteriously
258:       configuration.load_once_paths.freeze
259:     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 240
240:     def set_load_path
241:       load_paths = configuration.load_paths + configuration.framework_paths
242:       load_paths.reverse_each { |dir| $LOAD_PATH.unshift(dir) if File.directory?(dir) }
243:       $LOAD_PATH.uniq!
244:     end