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 118
118:     def initialize(configuration)
119:       @configuration = configuration
120:       @loaded_plugins = []
121:     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.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 109
109:     def self.run(command = :process, configuration = Configuration.new)
110:       yield configuration if block_given?
111:       initializer = new configuration
112:       initializer.send(command)
113:       initializer
114:     end

Public Instance methods

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 273
273:     def add_gem_load_paths
274:       Rails::GemDependency.add_frozen_gem_path
275:       unless @configuration.gems.empty?
276:         require "rubygems"
277:         @configuration.gems.each { |gem| gem.add_load_paths }
278:       end
279:     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 269
269:     def add_plugin_load_paths
270:       plugin_loader.add_plugin_load_paths
271:     end

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

[Source]

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

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

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 541
541:     def after_initialize
542:       if gems_dependencies_loaded
543:         configuration.after_initialize_blocks.each do |block|
544:           block.call
545:         end
546:       end
547:     end

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 285
285:     def check_gem_dependencies
286:       unloaded_gems = @configuration.gems.reject { |g| g.loaded? }
287:       if unloaded_gems.size > 0
288:         @gems_dependencies_loaded = false
289:         # don't print if the gems rake tasks are being run
290:         unless $rails_gem_installer
291:           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"
292:         end
293:       else
294:         @gems_dependencies_loaded = true
295:       end
296:     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 197
197:     def check_ruby_version
198:       require 'ruby_version_check'
199:     end

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 564
564:     def disable_dependency_loading
565:       if configuration.cache_classes && !configuration.dependency_loading
566:         ActiveSupport::Dependencies.unhook!
567:       end
568:     end

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 398
398:     def initialize_cache
399:       unless defined?(RAILS_CACHE)
400:         silence_warnings { Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store(configuration.cache_store) }
401:       end
402:     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 391
391:     def initialize_database
392:       if configuration.frameworks.include?(:active_record)
393:         ActiveRecord::Base.configurations = configuration.database_configuration
394:         ActiveRecord::Base.establish_connection
395:       end
396:     end

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

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 479
479:     def initialize_dependency_mechanism
480:       ActiveSupport::Dependencies.mechanism = configuration.cache_classes ? :require : :load
481:     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 383
383:     def initialize_encoding
384:       $KCODE='u' if RUBY_VERSION < '1.9'
385:     end

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 404
404:     def initialize_framework_caches
405:       if configuration.frameworks.include?(:action_controller)
406:         ActionController::Base.cache_store ||= RAILS_CACHE
407:       end
408:     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 446
446:     def initialize_framework_logging
447:       for framework in ([ :active_record, :action_controller, :action_mailer ] & configuration.frameworks)
448:         framework.to_s.camelize.constantize.const_get("Base").logger ||= Rails.logger
449:       end
450: 
451:       ActiveSupport::Dependencies.logger ||= Rails.logger
452:       Rails.cache.logger ||= Rails.logger
453:     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 527
527:     def initialize_framework_settings
528:       configuration.frameworks.each do |framework|
529:         base_class = framework.to_s.camelize.constantize.const_get("Base")
530: 
531:         configuration.send(framework).each do |setting, value|
532:           base_class.send("#{setting}=", value)
533:         end
534:       end
535:       configuration.active_support.each do |setting, value|
536:         ActiveSupport.send("#{setting}=", value)
537:       end
538:     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 459
459:     def initialize_framework_views
460:       if configuration.frameworks.include?(:action_view)
461:         view_path = ActionView::PathSet::Path.new(configuration.view_path, false)
462:         ActionMailer::Base.template_root ||= view_path if configuration.frameworks.include?(:action_mailer)
463:         ActionController::Base.view_paths = view_path if configuration.frameworks.include?(:action_controller) && ActionController::Base.view_paths.empty?
464:       end
465:     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.

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 514
514:     def initialize_i18n
515:       configuration.i18n.each do |setting, value|
516:         if setting == :load_path
517:           I18n.load_path += value
518:         else
519:           I18n.send("#{setting}=", value)
520:         end
521:       end
522:     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 418
418:     def initialize_logger
419:       # if the environment has explicitly defined a logger, use it
420:       return if Rails.logger
421: 
422:       unless logger = configuration.logger
423:         begin
424:           logger = ActiveSupport::BufferedLogger.new(configuration.log_path)
425:           logger.level = ActiveSupport::BufferedLogger.const_get(configuration.log_level.to_s.upcase)
426:           if configuration.environment == "production"
427:             logger.auto_flushing = false
428:           end
429:         rescue StandardError => e
430:           logger = ActiveSupport::BufferedLogger.new(STDERR)
431:           logger.level = ActiveSupport::BufferedLogger::WARN
432:           logger.warn(
433:             "Rails Error: Unable to access log file. Please ensure that #{configuration.log_path} exists and is chmod 0666. " +
434:             "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
435:           )
436:         end
437:       end
438: 
439:       silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }
440:     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 470
470:     def initialize_routing
471:       return unless configuration.frameworks.include?(:action_controller)
472:       ActionController::Routing.controller_paths = configuration.controller_paths
473:       ActionController::Routing::Routes.configuration_file = configuration.routes_configuration_file
474:       ActionController::Routing::Routes.reload
475:     end

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 489
489:     def initialize_temporary_session_directory
490:       if configuration.frameworks.include?(:action_controller)
491:         session_path = "#{configuration.root_path}/tmp/sessions/"
492:         ActionController::Base.session_options[:tmpdir] = File.exist?(session_path) ? session_path : Dir::tmpdir
493:       end
494:     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 498
498:     def initialize_time_zone
499:       if configuration.time_zone
500:         zone_default = Time.__send__(:get_zone, configuration.time_zone)
501:         unless zone_default
502:           raise %{Value assigned to config.time_zone not recognized. Run "rake -D time" for a list of tasks for finding appropriate time zone names.}
503:         end
504:         Time.zone_default = zone_default
505:         if configuration.frameworks.include?(:active_record)
506:           ActiveRecord::Base.time_zone_aware_attributes = true
507:           ActiveRecord::Base.default_timezone = :utc
508:         end
509:       end
510:     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 485
485:     def initialize_whiny_nils
486:       require('active_support/whiny_nil') if configuration.whiny_nils
487:     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 205
205:     def install_gem_spec_stubs
206:       unless Rails.respond_to?(:vendor_rails?)
207:         abort %{Your config/boot.rb is outdated: Run "rake rails:update".}
208:       end
209: 
210:       if Rails.vendor_rails?
211:         begin; require "rubygems"; rescue LoadError; return; end
212: 
213:         stubs = %w(rails activesupport activerecord actionpack actionmailer activeresource)
214:         stubs.reject! { |s| Gem.loaded_specs.key?(s) }
215: 
216:         stubs.each do |stub|
217:           Gem.loaded_specs[stub] = Gem::Specification.new do |s|
218:             s.name = stub
219:             s.version = Rails::VERSION::STRING
220:             s.loaded_from = ""
221:           end
222:         end
223:       end
224:     end

Eager load application classes

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 365
365:     def load_application_classes
366:       if configuration.cache_classes
367:         configuration.eager_load_paths.each do |load_path|
368:           matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/
369:           Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
370:             require_dependency file.sub(matcher, '\1')
371:           end
372:         end
373:       end
374:     end

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 549
549:     def load_application_initializers
550:       if gems_dependencies_loaded
551:         Dir["#{configuration.root_path}/config/initializers/**/*.rb"].sort.each do |initializer|
552:           load(initializer)
553:         end
554:       end
555:     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 334
334:     def load_environment
335:       silence_warnings do
336:         return if @environment_loaded
337:         @environment_loaded = true
338: 
339:         config = configuration
340:         constants = self.class.constants
341: 
342:         eval(IO.read(configuration.environment_path), binding, configuration.environment_path)
343: 
344:         (self.class.constants - constants).each do |const|
345:           Object.const_set(const, self.class.const_get(const))
346:         end
347:       end
348:     end

[Source]

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

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 350
350:     def load_observers
351:       if gems_dependencies_loaded && configuration.frameworks.include?(:active_record)
352:         ActiveRecord::Base.instantiate_observers
353:       end
354:     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 324
324:     def load_plugins
325:       plugin_loader.load_plugins
326:     end

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 356
356:     def load_view_paths
357:       if configuration.frameworks.include?(:action_view)
358:         ActionView::PathSet::Path.eager_load_templates! if configuration.cache_classes
359:         ActionController::Base.view_paths.load if configuration.frameworks.include?(:action_controller)
360:         ActionMailer::Base.template_root.load if configuration.frameworks.include?(:action_mailer)
361:       end
362:     end

[Source]

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

[Source]

     # File vendor/rails/railties/lib/initializer.rb, line 557
557:     def prepare_dispatcher
558:       return unless configuration.frameworks.include?(:action_controller)
559:       require 'dispatcher' unless defined?(::Dispatcher)
560:       Dispatcher.define_dispatcher_callbacks(configuration.cache_classes)
561:       Dispatcher.new(Rails.logger).send :run_callbacks, :prepare_dispatch
562:     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 125
125:     def process
126:       Rails.configuration = configuration
127: 
128:       check_ruby_version
129:       install_gem_spec_stubs
130:       set_load_path
131:       add_gem_load_paths
132: 
133:       require_frameworks
134:       set_autoload_paths
135:       add_plugin_load_paths
136:       load_environment
137: 
138:       initialize_encoding
139:       initialize_database
140: 
141:       initialize_cache
142:       initialize_framework_caches
143: 
144:       initialize_logger
145:       initialize_framework_logging
146: 
147:       initialize_dependency_mechanism
148:       initialize_whiny_nils
149:       initialize_temporary_session_directory
150: 
151:       initialize_time_zone
152:       initialize_i18n
153: 
154:       initialize_framework_settings
155:       initialize_framework_views
156: 
157:       add_support_load_paths
158: 
159:       load_gems
160:       load_plugins
161: 
162:       # pick up any gems that plugins depend on
163:       add_gem_load_paths
164:       load_gems
165:       check_gem_dependencies
166: 
167:       load_application_initializers
168: 
169:       # the framework is now fully initialized
170:       after_initialize
171: 
172:       # Prepare dispatcher callbacks and run 'prepare' callbacks
173:       prepare_dispatcher
174: 
175:       # Routing must be initialized after plugins to allow the former to extend the routes
176:       initialize_routing
177: 
178:       # Observers are loaded after plugins in case Observers or observed models are modified by plugins.
179:       load_observers
180: 
181:       # Load view path cache
182:       load_view_paths
183: 
184:       # Load application classes
185:       load_application_classes
186: 
187:       # Disable dependency loading during request cycle
188:       disable_dependency_loading
189: 
190:       # Flag initialized
191:       Rails.initialized = true
192:     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 256
256:     def require_frameworks
257:       configuration.frameworks.each { |framework| require(framework.to_s) }
258:     rescue LoadError => e
259:       # re-raise because Mongrel would swallow it
260:       raise e.to_s
261:     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 236
236:     def set_autoload_paths
237:       ActiveSupport::Dependencies.load_paths = configuration.load_paths.uniq
238:       ActiveSupport::Dependencies.load_once_paths = configuration.load_once_paths.uniq
239: 
240:       extra = ActiveSupport::Dependencies.load_once_paths - ActiveSupport::Dependencies.load_paths
241:       unless extra.empty?
242:         abort "load_once_paths must be a subset of the load_paths.\nExtra items in load_once_paths: \#{extra * ','}\n"
243:       end
244: 
245:       # Freeze the arrays so future modifications will fail rather than do nothing mysteriously
246:       configuration.load_once_paths.freeze
247:     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 228
228:     def set_load_path
229:       load_paths = configuration.load_paths + configuration.framework_paths
230:       load_paths.reverse_each { |dir| $LOAD_PATH.unshift(dir) if File.directory?(dir) }
231:       $LOAD_PATH.uniq!
232:     end

[Validate]