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.
- add_gem_load_paths
- add_plugin_load_paths
- add_support_load_paths
- after_initialize
- check_gem_dependencies
- check_ruby_version
- disable_dependency_loading
- initialize_cache
- initialize_database
- initialize_database_middleware
- initialize_dependency_mechanism
- initialize_encoding
- initialize_framework_caches
- initialize_framework_logging
- initialize_framework_settings
- initialize_framework_views
- initialize_i18n
- initialize_logger
- initialize_metal
- initialize_routing
- initialize_time_zone
- initialize_whiny_nils
- install_gem_spec_stubs
- load_application_classes
- load_application_initializers
- load_environment
- load_gems
- load_observers
- load_plugins
- load_view_paths
- new
- plugin_loader
- preload_frameworks
- prepare_dispatcher
- process
- require_frameworks
- run
- set_autoload_paths
- set_load_path
| [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. |
Create a new Initializer instance that references the given Configuration instance.
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.
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).
Add the load paths used by support functions such as the info controller
Fires the user-supplied after_initialize block (Configuration#after_initialize)
# File railties/lib/initializer.rb, line 310
310: def check_gem_dependencies
311: unloaded_gems = @configuration.gems.reject { |g| g.loaded? }
312: if unloaded_gems.size > 0
313: @gems_dependencies_loaded = false
314: # don't print if the gems rake tasks are being run
315: unless $gems_rake_task
316: 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"
317: end
318: else
319: @gems_dependencies_loaded = true
320: end
321: 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 railties/lib/initializer.rb, line 435
435: def initialize_cache
436: unless defined?(RAILS_CACHE)
437: silence_warnings { Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store(configuration.cache_store) }
438:
439: if RAILS_CACHE.respond_to?(:middleware)
440: # Insert middleware to setup and teardown local cache for each request
441: configuration.middleware.insert_after("ActionController::Failsafe""ActionController::Failsafe", RAILS_CACHE.middleware)
442: end
443: end
444: 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 railties/lib/initializer.rb, line 423
423: def initialize_database_middleware
424: if configuration.frameworks.include?(:active_record)
425: if ActionController::Base.session_store == ActiveRecord::SessionStore
426: configuration.middleware.insert_before "ActiveRecord::SessionStore""ActiveRecord::SessionStore", ActiveRecord::ConnectionAdapters::ConnectionManagement
427: configuration.middleware.insert_before "ActiveRecord::SessionStore""ActiveRecord::SessionStore", ActiveRecord::QueryCache
428: else
429: configuration.middleware.use ActiveRecord::ConnectionAdapters::ConnectionManagement
430: configuration.middleware.use ActiveRecord::QueryCache
431: end
432: end
433: end
Sets the dependency loading mechanism based on the value of Configuration#cache_classes.
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.
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 488
488: def initialize_framework_logging
489: for framework in ([ :active_record, :action_controller, :action_mailer ] & configuration.frameworks)
490: framework.to_s.camelize.constantize.const_get("Base").logger ||= Rails.logger
491: end
492:
493: ActiveSupport::Dependencies.logger ||= Rails.logger
494: Rails.cache.logger ||= Rails.logger
495: 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 railties/lib/initializer.rb, line 577
577: def initialize_framework_settings
578: configuration.frameworks.each do |framework|
579: base_class = framework.to_s.camelize.constantize.const_get("Base")
580:
581: configuration.send(framework).each do |setting, value|
582: base_class.send("#{setting}=", value)
583: end
584: end
585: configuration.active_support.each do |setting, value|
586: ActiveSupport.send("#{setting}=", value)
587: end
588: 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 railties/lib/initializer.rb, line 501
501: def initialize_framework_views
502: if configuration.frameworks.include?(:action_view)
503: view_path = ActionView::PathSet.type_cast(configuration.view_path)
504: ActionMailer::Base.template_root = view_path if configuration.frameworks.include?(:action_mailer) && ActionMailer::Base.view_paths.blank?
505: ActionController::Base.view_paths = view_path if configuration.frameworks.include?(:action_controller) && ActionController::Base.view_paths.blank?
506: end
507: 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.
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 460
460: def initialize_logger
461: # if the environment has explicitly defined a logger, use it
462: return if Rails.logger
463:
464: unless logger = configuration.logger
465: begin
466: logger = ActiveSupport::BufferedLogger.new(configuration.log_path)
467: logger.level = ActiveSupport::BufferedLogger.const_get(configuration.log_level.to_s.upcase)
468: if configuration.environment == "production"
469: logger.auto_flushing = false
470: end
471: rescue StandardError => e
472: logger = ActiveSupport::BufferedLogger.new(STDERR)
473: logger.level = ActiveSupport::BufferedLogger::WARN
474: logger.warn(
475: "Rails Error: Unable to access log file. Please ensure that #{configuration.log_path} exists and is chmod 0666. " +
476: "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
477: )
478: end
479: end
480:
481: silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }
482: end
# File railties/lib/initializer.rb, line 565
565: def initialize_metal
566: Rails::Rack::Metal.requested_metals = configuration.metals
567: Rails::Rack::Metal.metal_paths += plugin_loader.engine_metal_paths
568:
569: configuration.middleware.insert_before(
570: "ActionController::RewindableInput""ActionController::RewindableInput",
571: Rails::Rack::Metal, :if => Rails::Rack::Metal.metals.any?)
572: 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 railties/lib/initializer.rb, line 512
512: def initialize_routing
513: return unless configuration.frameworks.include?(:action_controller)
514:
515: ActionController::Routing.controller_paths += configuration.controller_paths
516: ActionController::Routing::Routes.add_configuration_file(configuration.routes_configuration_file)
517: ActionController::Routing::Routes.reload!
518: 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 railties/lib/initializer.rb, line 534
534: def initialize_time_zone
535: if configuration.time_zone
536: zone_default = Time.__send__(:get_zone, configuration.time_zone)
537:
538: unless zone_default
539: raise \
540: 'Value assigned to config.time_zone not recognized.' +
541: 'Run "rake -D time" for a list of tasks for finding appropriate time zone names.'
542: end
543:
544: Time.zone_default = zone_default
545:
546: if configuration.frameworks.include?(:active_record)
547: ActiveRecord::Base.time_zone_aware_attributes = true
548: ActiveRecord::Base.default_timezone = :utc
549: end
550: end
551: end
Loads support for "whiny nil" (noisy warnings when methods are invoked on nil values) if Configuration#whiny_nils is true.
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 215
215: def install_gem_spec_stubs
216: unless Rails.respond_to?(:vendor_rails?)
217: abort %{Your config/boot.rb is outdated: Run "rake rails:update".}
218: end
219:
220: if Rails.vendor_rails?
221: begin; require "rubygems"; rescue LoadError; return; end
222:
223: stubs = %w(rails activesupport activerecord actionpack actionmailer activeresource)
224: stubs.reject! { |s| Gem.loaded_specs.key?(s) }
225:
226: stubs.each do |stub|
227: Gem.loaded_specs[stub] = Gem::Specification.new do |s|
228: s.name = stub
229: s.version = Rails::VERSION::STRING
230: s.loaded_from = ""
231: end
232: end
233: end
234: end
Eager load application classes
# File railties/lib/initializer.rb, line 389
389: def load_application_classes
390: return if $rails_rake_task
391: if configuration.cache_classes
392: configuration.eager_load_paths.each do |load_path|
393: matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/
394: Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
395: require_dependency file.sub(matcher, '\1')
396: end
397: end
398: end
399: end
Loads the environment specified by Configuration#environment_path, which is typically one of development, test, or production.
# File railties/lib/initializer.rb, line 359
359: def load_environment
360: silence_warnings do
361: return if @environment_loaded
362: @environment_loaded = true
363:
364: config = configuration
365: constants = self.class.constants
366:
367: eval(IO.read(configuration.environment_path), binding, configuration.environment_path)
368:
369: (self.class.constants - constants).each do |const|
370: Object.const_set(const, self.class.const_get(const))
371: end
372: end
373: 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
# File railties/lib/initializer.rb, line 381
381: def load_view_paths
382: if configuration.frameworks.include?(:action_view)
383: ActionController::Base.view_paths.load! if configuration.frameworks.include?(:action_controller)
384: ActionMailer::Base.view_paths.load! if configuration.frameworks.include?(:action_mailer)
385: end
386: end
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 276
276: def preload_frameworks
277: if configuration.preload_frameworks
278: configuration.frameworks.each do |framework|
279: # String#classify and #constantize aren't available yet.
280: toplevel = Object.const_get(framework.to_s.gsub(/(?:^|_)(.)/) { $1.upcase })
281: toplevel.load_all! if toplevel.respond_to?(:load_all!)
282: end
283: end
284: end
# File railties/lib/initializer.rb, line 607
607: def prepare_dispatcher
608: return unless configuration.frameworks.include?(:action_controller)
609: require 'dispatcher' unless defined?(::Dispatcher)
610: Dispatcher.define_dispatcher_callbacks(configuration.cache_classes)
611: Dispatcher.run_prepare_callbacks
612: end
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: load_gems
163: load_plugins
164:
165: # pick up any gems that plugins depend on
166: add_gem_load_paths
167: load_gems
168: check_gem_dependencies
169:
170: # bail out if gems are missing - note that check_gem_dependencies will have
171: # already called abort() unless $gems_rake_task is set
172: return unless gems_dependencies_loaded
173:
174: load_application_initializers
175:
176: # the framework is now fully initialized
177: after_initialize
178:
179: # Setup database middleware after initializers have run
180: initialize_database_middleware
181:
182: # Prepare dispatcher callbacks and run 'prepare' callbacks
183: prepare_dispatcher
184:
185: # Routing must be initialized after plugins to allow the former to extend the routes
186: initialize_routing
187:
188: # Observers are loaded after plugins in case Observers or observed models are modified by plugins.
189: load_observers
190:
191: # Load view path cache
192: load_view_paths
193:
194: # Load application classes
195: load_application_classes
196:
197: # Disable dependency loading during request cycle
198: disable_dependency_loading
199:
200: # Flag initialized
201: Rails.initialized = true
202: 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.
Set the paths from which Rails will automatically load source files, and the load_once paths.
# File railties/lib/initializer.rb, line 246
246: def set_autoload_paths
247: ActiveSupport::Dependencies.load_paths = configuration.load_paths.uniq
248: ActiveSupport::Dependencies.load_once_paths = configuration.load_once_paths.uniq
249:
250: extra = ActiveSupport::Dependencies.load_once_paths - ActiveSupport::Dependencies.load_paths
251: unless extra.empty?
252: abort "load_once_paths must be a subset of the load_paths.\nExtra items in load_once_paths: \#{extra * ','}\n"
253: end
254:
255: # Freeze the arrays so future modifications will fail rather than do nothing mysteriously
256: configuration.load_once_paths.freeze
257: end
Set the $LOAD_PATH based on the value of Configuration#load_paths. Duplicates are removed.