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.
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. |
Create a new Initializer instance that references the given Configuration instance.
# 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.
# 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
# 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).
# 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
# 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)
# 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
# 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.
# File vendor/rails/railties/lib/initializer.rb, line 197 197: def check_ruby_version 198: require 'ruby_version_check' 199: end
# 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
# 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.
# 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.
# 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.
# File vendor/rails/railties/lib/initializer.rb, line 383 383: def initialize_encoding 384: $KCODE='u' if RUBY_VERSION < '1.9' 385: end
# 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.
# 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.
# 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.
# 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.
# 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.
# 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).
# 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
# 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.
# 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.
# 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.
# 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
# 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
# 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.
# 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
# File vendor/rails/railties/lib/initializer.rb, line 281 281: def load_gems 282: @configuration.gems.each { |gem| gem.load } 283: end
# 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:
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 vendor/rails/railties/lib/initializer.rb, line 324 324: def load_plugins 325: plugin_loader.load_plugins 326: end
# 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
# File vendor/rails/railties/lib/initializer.rb, line 328 328: def plugin_loader 329: @plugin_loader ||= configuration.plugin_loader.new(self) 330: end
# 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).
# 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.
# 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.
# 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.
# 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