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_web_service ]
end

This will use the default configuration options from Rails::Configuration, but allow for overwriting on select areas.

Methods
A
C
F
I
L
N
P
R
S
Constants
RAILS_ROOT = '.'
 
Attributes
[R] configuration

The Configuration instance used by this Initializer instance.

[R] loaded_plugins

The set of loaded plugins.

Class Public methods
new(configuration)

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

# File rails/railties/lib/initializer.rb, line 53
def initialize(configuration)
  @configuration = configuration
  @loaded_plugins = []
end
run(command = :process, configuration = Configuration.new)

Runs the initializer. By default, this will invoke the process method, which simply executes all of the initialization routines. Alternately, you can specify explicitly which initialization routine you want:

Rails::Initializer.run(:set_load_path)

This is useful if you only want the load path initialized, without incuring the overhead of completely loading the entire environment.

# File rails/railties/lib/initializer.rb, line 44
def self.run(command = :process, configuration = Configuration.new)
  yield configuration if block_given?
  initializer = new configuration
  initializer.send(command)
  initializer
end
Instance Public methods
add_support_load_paths()

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

# File rails/railties/lib/initializer.rb, line 170
def add_support_load_paths
end
after_initialize()
# File rails/railties/lib/initializer.rb, line 340
def after_initialize
  configuration.after_initialize_block.call if configuration.after_initialize_block
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 rails/railties/lib/initializer.rb, line 124
def check_ruby_version
  require 'ruby_version_check'
end
initialize_breakpoints()

Sets the BREAKPOINT_SERVER_PORT if Rails::Configuration#breakpoint_server is true.

# File rails/railties/lib/initializer.rb, line 304
def initialize_breakpoints
  silence_warnings { Object.const_set("BREAKPOINT_SERVER_PORT", 42531) if configuration.breakpoint_server }
end
initialize_database()

This initialization routine does nothing unless :active_record is one of the frameworks to load (Rails::Configuration#frameworks). If it is, this sets the database configuration from Rails::Configuration#database_configuration and then establishes the connection.

# File rails/railties/lib/initializer.rb, line 232
def initialize_database
  return unless configuration.frameworks.include?(:active_record)
  ActiveRecord::Base.configurations = configuration.database_configuration
  ActiveRecord::Base.establish_connection
end
initialize_dependency_mechanism()

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

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

This initialzation 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

# File rails/railties/lib/initializer.rb, line 224
def initialize_encoding
  $KCODE='u'
end
initialize_framework_logging()

Sets the logger for ActiveRecord, ActionController, and ActionMailer (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 rails/railties/lib/initializer.rb, line 271
def initialize_framework_logging
  for framework in ([ :active_record, :action_controller, :action_mailer ] & configuration.frameworks)
    framework.to_s.camelize.constantize.const_get("Base").logger ||= RAILS_DEFAULT_LOGGER
  end
end
initialize_framework_settings()

Initializes framework-specific settings for each of the loaded frameworks (Rails::Configuration#frameworks). The available settings map to the accessors on each of the corresponding Base classes.

# File rails/railties/lib/initializer.rb, line 329
def initialize_framework_settings
  configuration.frameworks.each do |framework|
    base_class = framework.to_s.camelize.constantize.const_get("Base")

    configuration.send(framework).each do |setting, value|
      base_class.send("#{setting}=", value)
    end
  end
end
initialize_framework_views()

Sets the template_root for ActionController::Base and ActionMailer::Base (but only for those frameworks that are to be loaded). If the framework’s template_root has already been set, it is not changed, otherwise it is set to use Rails::Configuration#view_path.

# File rails/railties/lib/initializer.rb, line 281
def initialize_framework_views
  for framework in ([ :action_controller, :action_mailer ] & configuration.frameworks)
    framework.to_s.camelize.constantize.const_get("Base").template_root ||= configuration.view_path
  end
end
initialize_logger()

If the RAILS_DEFAULT_LOGGER constant is already set, this initialization routine does nothing. If the constant is not set, and Rails::Configuration#logger is not nil, this also does nothing. Otherwise, a new logger instance is created at Rails::Configuration#log_path, with a default log level of Rails::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 rails/railties/lib/initializer.rb, line 246
def initialize_logger
  # if the environment has explicitly defined a logger, use it
  return if defined?(RAILS_DEFAULT_LOGGER)

  unless logger = configuration.logger
    begin
      logger = Logger.new(configuration.log_path)
      logger.level = Logger.const_get(configuration.log_level.to_s.upcase)
    rescue StandardError
      logger = Logger.new(STDERR)
      logger.level = Logger::WARN
      logger.warn(
        "Rails Error: Unable to access log file. Please ensure that #{configuration.log_path} exists and is chmod 0666. " +
        "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
      )
    end
  end

  silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }
end
initialize_routing()

If ActionController is not one of the loaded frameworks (Rails::Configuration#frameworks) this does nothing. Otherwise, it loads the routing definitions and sets up loading module used to lazily load controllers (Rails::Configuration#controller_paths).

# File rails/railties/lib/initializer.rb, line 290
def initialize_routing
  return unless configuration.frameworks.include?(:action_controller)
  ActionController::Routing.controller_paths = configuration.controller_paths
  ActionController::Routing::Routes.reload
end
initialize_temporary_directories()
# File rails/railties/lib/initializer.rb, line 314
def initialize_temporary_directories
  if configuration.frameworks.include?(:action_controller)
    session_path = "#{configuration.root_path}/tmp/sessions/"
    ActionController::Base.session_options[:tmpdir] = File.exist?(session_path) ? session_path : Dir::tmpdir

    cache_path = "#{configuration.root_path}/tmp/cache/"
    if File.exist?(cache_path)
      ActionController::Base.fragment_cache_store = :file_store, cache_path
    end
  end
end
initialize_whiny_nils()

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

# File rails/railties/lib/initializer.rb, line 310
def initialize_whiny_nils
  require('active_support/whiny_nil') if configuration.whiny_nils
end
load_environment()

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

# File rails/railties/lib/initializer.rb, line 204
def load_environment
  silence_warnings do
    config = configuration
    constants = self.class.constants
    
    eval(IO.read(configuration.environment_path), binding, configuration.environment_path)
    
    (self.class.constants - constants).each do |const|
      Object.const_set(const, self.class.const_get(const))
    end
  end
end
load_observers()
# File rails/railties/lib/initializer.rb, line 217
def load_observers
  ActiveRecord::Base.instantiate_observers
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 = ['lib/plugins', 'vendor/plugins']

Each plugin discovered in plugin_paths is initialized:

  • add its lib directory, if present, to the beginning of the load path

  • evaluate init.rb 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, the plugins will be loaded in that order. Otherwise, plugins are loaded in alphabetical order.

# File rails/railties/lib/initializer.rb, line 186
def load_plugins
  if configuration.plugins.nil?
    # a nil value implies we don't care about plugins; load 'em all in a reliable order
    find_plugins(configuration.plugin_paths).sort.each { |path| load_plugin path }
  elsif !configuration.plugins.empty?
    # we've specified a config.plugins array, so respect that order
    plugin_paths = find_plugins(configuration.plugin_paths)
    configuration.plugins.each do |name|
      path = plugin_paths.find { |p| File.basename(p) == name }
      raise(LoadError, "Cannot find the plugin '#{name}'!") if path.nil?
      load_plugin path
    end
  end
  $LOAD_PATH.uniq!
end
process()

Sequentially step through all of the available initialization routines, in order:

(Note that load_environment is invoked twice, once at the start and once at the end, to support the legacy configuration style where the environment could overwrite the defaults directly, instead of via the Configuration instance.

# File rails/railties/lib/initializer.rb, line 82
def process
  check_ruby_version
  set_load_path
  set_connection_adapters

  require_frameworks
  set_autoload_paths
  load_environment

  initialize_encoding
  initialize_database
  initialize_logger
  initialize_framework_logging
  initialize_framework_views
  initialize_dependency_mechanism
  initialize_breakpoints
  initialize_whiny_nils
  initialize_temporary_directories
  initialize_framework_settings

  # Support for legacy configuration style where the environment
  # could overwrite anything set from the defaults/global through
  # the individual base class configurations.
  load_environment

  add_support_load_paths

  load_plugins

  # Observers are loaded after plugins in case Observers or observed models are modified by plugins.
  load_observers

  # Routing must be initialized after plugins to allow the former to extend the routes
  initialize_routing

  # the framework is now fully initialized
  after_initialize
end
require_frameworks()

Requires all frameworks specified by the Rails::Configuration#frameworks list. By default, all frameworks (ActiveRecord, ActiveSupport, ActionPack, ActionMailer, and ActionWebService) are loaded.

# File rails/railties/lib/initializer.rb, line 165
def require_frameworks
  configuration.frameworks.each { |framework| require(framework.to_s) }
end
set_autoload_paths()

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

# File rails/railties/lib/initializer.rb, line 138
    def set_autoload_paths
      Dependencies.load_paths = configuration.load_paths.uniq
      Dependencies.load_once_paths = configuration.load_once_paths.uniq

      extra = Dependencies.load_once_paths - Dependencies.load_paths
      unless extra.empty?
        abort "          load_once_paths must be a subset of the load_paths.
          Extra items in load_once_paths: #{extra * ','}
"
      end

      # Freeze the arrays so future modifications will fail rather than do nothing mysteriously
      configuration.load_once_paths.freeze
    end
set_connection_adapters()

Sets the RAILS_CONNECTION_ADAPTERS constant based on the value of Rails::Configuration#connection_adapters. This constant is used to determine which database adapters should be loaded (by default, all adapters are loaded).

# File rails/railties/lib/initializer.rb, line 158
def set_connection_adapters
  Object.const_set("RAILS_CONNECTION_ADAPTERS", configuration.connection_adapters) if configuration.connection_adapters
end
set_load_path()

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

# File rails/railties/lib/initializer.rb, line 130
def set_load_path
  load_paths = configuration.load_paths + configuration.framework_paths
  load_paths.reverse_each { |dir| $LOAD_PATH.unshift(dir) if File.directory?(dir) }
  $LOAD_PATH.uniq!
end
Instance Protected methods
find_plugins(*base_paths)

Return a list of plugin paths within base_path. A plugin path is a directory that contains either a lib directory or an init.rb file. This recurses into directories which are not plugin paths, so you may organize your plugins within the plugin path.

# File rails/railties/lib/initializer.rb, line 349
def find_plugins(*base_paths)
  base_paths.flatten.inject([]) do |plugins, base_path|
    Dir.glob(File.join(base_path, '*')).each do |path|
      if plugin_path?(path)
        plugins << path if plugin_enabled?(path)
      elsif File.directory?(path)
        plugins += find_plugins(path)
      end
    end
    plugins
  end
end
load_plugin(directory)

Load the plugin at path unless already loaded.

Each plugin is initialized:

  • add its lib directory, if present, to the beginning of the load path

  • evaluate init.rb if present

Returns true if the plugin is successfully loaded or false if it is already loaded (similar to Kernel#require). Raises LoadError if the plugin is not found.

# File rails/railties/lib/initializer.rb, line 379
def load_plugin(directory)
  name = File.basename(directory)
  return false if loaded_plugins.include?(name)

  # Catch nonexistent and empty plugins.
  raise LoadError, "No such plugin: #{directory}" unless plugin_path?(directory)

  lib_path  = File.join(directory, 'lib')
  init_path = File.join(directory, 'init.rb')
  has_lib   = File.directory?(lib_path)
  has_init  = File.file?(init_path)

  # Add lib to load path *after* the application lib, to allow
  # application libraries to override plugin libraries.
  if has_lib
    application_lib_index = $LOAD_PATH.index(File.join(RAILS_ROOT, "lib")) || 0
    $LOAD_PATH.insert(application_lib_index + 1, lib_path)
    Dependencies.load_paths << lib_path
    Dependencies.load_once_paths << lib_path
  end

  # Allow plugins to reference the current configuration object
  config = configuration
  
  # Add to set of loaded plugins before 'name' collapsed in eval.
  loaded_plugins << name

  # Evaluate init.rb.
  silence_warnings { eval(IO.read(init_path), binding, init_path) } if has_init

  true
end
plugin_enabled?(path)
# File rails/railties/lib/initializer.rb, line 366
def plugin_enabled?(path)
  configuration.plugins.nil? || configuration.plugins.include?(File.basename(path))
end
plugin_path?(path)
# File rails/railties/lib/initializer.rb, line 362
def plugin_path?(path)
  File.directory?(path) and (File.directory?(File.join(path, 'lib')) or File.file?(File.join(path, 'init.rb')))
end