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.

Methods

Attributes

configuration  [R]  The Configuration instance used by this Initializer instance.
gems_dependencies_loaded  [R]  Whether or not all the gem dependencies have been met
loaded_plugins  [R]  The set of loaded plugins.

Public Class methods

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

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 103
103:     def initialize(configuration)
104:       @configuration = configuration
105:       @loaded_plugins = []
106:     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.

[Source]

    # File vendor/rails/railties/lib/initializer.rb, line 94
94:     def self.run(command = :process, configuration = Configuration.new)
95:       yield configuration if block_given?
96:       initializer = new configuration
97:       initializer.send(command)
98:       initializer
99:     end

Public Instance methods

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 243
243:     def add_gem_load_paths
244:       unless @configuration.gems.empty?
245:         require "rubygems"
246:         @configuration.gems.each { |gem| gem.add_load_paths }
247:       end
248:     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).

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 239
239:     def add_plugin_load_paths
240:       plugin_loader.add_plugin_load_paths
241:     end

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

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 234
234:     def add_support_load_paths
235:     end

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

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 475
475:     def after_initialize
476:       if gems_dependencies_loaded
477:         configuration.after_initialize_blocks.each do |block|
478:           block.call
479:         end
480:       end
481:     end

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 254
254:     def check_gem_dependencies
255:       unloaded_gems = @configuration.gems.reject { |g| g.loaded? }
256:       if unloaded_gems.size > 0
257:         @gems_dependencies_loaded = false
258:         # don't print if the gems rake tasks are being run
259:         unless $rails_gem_installer
260:           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"
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.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 168
168:     def check_ruby_version
169:       require 'ruby_version_check'
170:     end

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 347
347:     def initialize_cache
348:       unless defined?(RAILS_CACHE)
349:         silence_warnings { Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store(configuration.cache_store) }
350:       end
351:     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.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 340
340:     def initialize_database
341:       if configuration.frameworks.include?(:active_record)
342:         ActiveRecord::Base.configurations = configuration.database_configuration
343:         ActiveRecord::Base.establish_connection
344:       end
345:     end

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

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 425
425:     def initialize_dependency_mechanism
426:       ActiveSupport::Dependencies.mechanism = configuration.cache_classes ? :require : :load
427:     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.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 332
332:     def initialize_encoding
333:       $KCODE='u' if RUBY_VERSION < '1.9'
334:     end

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 353
353:     def initialize_framework_caches
354:       if configuration.frameworks.include?(:action_controller)
355:         ActionController::Base.cache_store ||= RAILS_CACHE
356:       end
357:     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.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 396
396:     def initialize_framework_logging
397:       for framework in ([ :active_record, :action_controller, :action_mailer ] & configuration.frameworks)
398:         framework.to_s.camelize.constantize.const_get("Base").logger ||= RAILS_DEFAULT_LOGGER
399:       end
400:       
401:       RAILS_CACHE.logger ||= RAILS_DEFAULT_LOGGER
402:     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.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 461
461:     def initialize_framework_settings
462:       configuration.frameworks.each do |framework|
463:         base_class = framework.to_s.camelize.constantize.const_get("Base")
464: 
465:         configuration.send(framework).each do |setting, value|
466:           base_class.send("#{setting}=", value)
467:         end
468:       end
469:       configuration.active_support.each do |setting, value|
470:         ActiveSupport.send("#{setting}=", value)
471:       end
472:     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.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 408
408:     def initialize_framework_views
409:       ActionMailer::Base.template_root ||= configuration.view_path  if configuration.frameworks.include?(:action_mailer)
410:       ActionController::Base.view_paths = [configuration.view_path] if configuration.frameworks.include?(:action_controller) && ActionController::Base.view_paths.empty?
411:     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.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 367
367:     def initialize_logger
368:       # if the environment has explicitly defined a logger, use it
369:       return if defined?(RAILS_DEFAULT_LOGGER)
370: 
371:       unless logger = configuration.logger
372:         begin
373:           logger = ActiveSupport::BufferedLogger.new(configuration.log_path)
374:           logger.level = ActiveSupport::BufferedLogger.const_get(configuration.log_level.to_s.upcase)
375:           if configuration.environment == "production"
376:             logger.auto_flushing = false
377:             logger.set_non_blocking_io
378:           end
379:         rescue StandardError => e
380:           logger = ActiveSupport::BufferedLogger.new(STDERR)
381:           logger.level = ActiveSupport::BufferedLogger::WARN
382:           logger.warn(
383:             "Rails Error: Unable to access log file. Please ensure that #{configuration.log_path} exists and is chmod 0666. " +
384:             "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
385:           )
386:         end
387:       end
388: 
389:       silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }
390:     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).

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 416
416:     def initialize_routing
417:       return unless configuration.frameworks.include?(:action_controller)
418:       ActionController::Routing.controller_paths = configuration.controller_paths
419:       ActionController::Routing::Routes.configuration_file = configuration.routes_configuration_file
420:       ActionController::Routing::Routes.reload
421:     end

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 435
435:     def initialize_temporary_session_directory
436:       if configuration.frameworks.include?(:action_controller)
437:         session_path = "#{configuration.root_path}/tmp/sessions/"
438:         ActionController::Base.session_options[:tmpdir] = File.exist?(session_path) ? session_path : Dir::tmpdir
439:       end
440:     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.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 444
444:     def initialize_time_zone
445:       if configuration.time_zone
446:         zone_default = Time.send!(:get_zone, configuration.time_zone)
447:         unless zone_default
448:           raise %{Value assigned to config.time_zone not recognized. Run "rake -D time" for a list of tasks for finding appropriate time zone names.}
449:         end
450:         Time.zone_default = zone_default
451:         if configuration.frameworks.include?(:active_record)
452:           ActiveRecord::Base.time_zone_aware_attributes = true
453:           ActiveRecord::Base.default_timezone = :utc
454:         end
455:       end
456:     end

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

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 431
431:     def initialize_whiny_nils
432:       require('active_support/whiny_nil') if configuration.whiny_nils
433:     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.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 176
176:     def install_gem_spec_stubs
177:       unless Rails.respond_to?(:vendor_rails?)
178:         abort %{Your config/boot.rb is outdated: Run "rake rails:update".}
179:       end
180: 
181:       if Rails.vendor_rails?
182:         begin; require "rubygems"; rescue LoadError; return; end
183: 
184:         stubs = %w(rails activesupport activerecord actionpack actionmailer activeresource)
185:         stubs.reject! { |s| Gem.loaded_specs.key?(s) }
186: 
187:         stubs.each do |stub|
188:           Gem.loaded_specs[stub] = Gem::Specification.new do |s|
189:             s.name = stub
190:             s.version = Rails::VERSION::STRING
191:           end
192:         end
193:       end
194:     end

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 483
483:     def load_application_initializers
484:       if gems_dependencies_loaded
485:         Dir["#{configuration.root_path}/config/initializers/**/*.rb"].sort.each do |initializer|
486:           load(initializer)
487:         end
488:       end
489:     end

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

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 303
303:     def load_environment
304:       silence_warnings do
305:         return if @environment_loaded
306:         @environment_loaded = true
307:         
308:         config = configuration
309:         constants = self.class.constants
310:         
311:         eval(IO.read(configuration.environment_path), binding, configuration.environment_path)
312:         
313:         (self.class.constants - constants).each do |const|
314:           Object.const_set(const, self.class.const_get(const))
315:         end
316:       end
317:     end

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 250
250:     def load_gems
251:       @configuration.gems.each { |gem| gem.load }
252:     end

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 319
319:     def load_observers
320:       if gems_dependencies_loaded && configuration.frameworks.include?(:active_record)
321:         ActiveRecord::Base.instantiate_observers
322:       end
323:     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

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 293
293:     def load_plugins
294:       plugin_loader.load_plugins
295:     end

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 297
297:     def plugin_loader
298:       @plugin_loader ||= configuration.plugin_loader.new(self)
299:     end

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 491
491:     def prepare_dispatcher
492:       return unless configuration.frameworks.include?(:action_controller)
493:       require 'dispatcher' unless defined?(::Dispatcher)
494:       Dispatcher.define_dispatcher_callbacks(configuration.cache_classes)
495:       Dispatcher.new(RAILS_DEFAULT_LOGGER).send :run_callbacks, :prepare_dispatch
496:     end

Sequentially step through all of the available initialization routines, in order (view execution order in source).

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 110
110:     def process
111:       Rails.configuration = configuration
112: 
113:       check_ruby_version
114:       install_gem_spec_stubs
115:       set_load_path
116:       add_gem_load_paths
117: 
118:       require_frameworks
119:       set_autoload_paths
120:       add_plugin_load_paths
121:       load_environment
122: 
123:       initialize_encoding
124:       initialize_database
125: 
126:       initialize_cache
127:       initialize_framework_caches
128: 
129:       initialize_logger
130:       initialize_framework_logging
131: 
132:       initialize_framework_views
133:       initialize_dependency_mechanism
134:       initialize_whiny_nils
135:       initialize_temporary_session_directory
136:       initialize_time_zone
137:       initialize_framework_settings
138: 
139:       add_support_load_paths
140: 
141:       load_gems
142:       load_plugins
143: 
144:       # pick up any gems that plugins depend on
145:       add_gem_load_paths
146:       load_gems
147:       check_gem_dependencies
148:       
149:       load_application_initializers
150: 
151:       # the framework is now fully initialized
152:       after_initialize
153: 
154:       # Prepare dispatcher callbacks and run 'prepare' callbacks
155:       prepare_dispatcher
156: 
157:       # Routing must be initialized after plugins to allow the former to extend the routes
158:       initialize_routing
159: 
160:       # Observers are loaded after plugins in case Observers or observed models are modified by plugins.
161:       
162:       load_observers
163:     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.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 226
226:     def require_frameworks
227:       configuration.frameworks.each { |framework| require(framework.to_s) }
228:     rescue LoadError => e
229:       # re-raise because Mongrel would swallow it
230:       raise e.to_s
231:     end

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

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 206
206:     def set_autoload_paths
207:       ActiveSupport::Dependencies.load_paths = configuration.load_paths.uniq
208:       ActiveSupport::Dependencies.load_once_paths = configuration.load_once_paths.uniq
209: 
210:       extra = ActiveSupport::Dependencies.load_once_paths - ActiveSupport::Dependencies.load_paths
211:       unless extra.empty?
212:         abort "load_once_paths must be a subset of the load_paths.\nExtra items in load_once_paths: \#{extra * ','}\n"
213:       end
214: 
215:       # Freeze the arrays so future modifications will fail rather than do nothing mysteriously
216:       configuration.load_once_paths.freeze
217:     end

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

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 198
198:     def set_load_path
199:       load_paths = configuration.load_paths + configuration.framework_paths
200:       load_paths.reverse_each { |dir| $LOAD_PATH.unshift(dir) if File.directory?(dir) }
201:       $LOAD_PATH.uniq!
202:     end

[Validate]