Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 454 lines (385 sloc) 16.236 kb
accd9b4 @josh Restore "Start Rails::Application object
josh authored
1 module Rails
2 class Application
897164d Conceptually unify instance & global initializers
Yehuda Katz + Carl Lerche authored
3 include Initializable
6d6ae08 Start moving the initializers into the application object
Carl Lerche authored
4
e4d7e50 Moving more initializers into the application object
Carl Lerche authored
5 class << self
d859402 @josh Use Rails.initialize! where we just want to run the initializers and are...
josh authored
6 # Stub out App initialize
7 def initialize!
8 new
9 end
10
897164d Conceptually unify instance & global initializers
Yehuda Katz + Carl Lerche authored
11 def new
b0b4ae9 test.rb, dev.rb, and production.rb just reopen the Application class; no...
Carlhuda authored
12 @instance ||= begin
13 begin
14 require config.environment_path
15 rescue LoadError
16 end
17 super
18 end
897164d Conceptually unify instance & global initializers
Yehuda Katz + Carl Lerche authored
19 end
20
e4d7e50 Moving more initializers into the application object
Carl Lerche authored
21 def config
1b27f5c Add the ability for plugins to set default configuration settings.
Carl Lerche authored
22 @config ||= begin
23 config = Configuration.new
24 Plugin.plugins.each { |p| config.merge(p.config) }
25 config
26 end
e4d7e50 Moving more initializers into the application object
Carl Lerche authored
27 end
6f6a589 Create the application object from config/environment.rb
Yehuda Katz + Carl Lerche authored
28
e4d7e50 Moving more initializers into the application object
Carl Lerche authored
29 # TODO: change the plugin loader to use config
30 alias configuration config
c9d4529 Change Rails::Application to a class that is inherited from.
Carl Lerche authored
31
e4d7e50 Moving more initializers into the application object
Carl Lerche authored
32 def config=(config)
33 @config = config
34 end
c9d4529 Change Rails::Application to a class that is inherited from.
Carl Lerche authored
35
bf9819f Have Rails.root be based off of config.ru
Carl Lerche authored
36 def root
37 config.root
38 end
39
530b8ff Have script/* and Rakefile use the application object
Carlhuda authored
40 def load_tasks
41 require "rails/tasks"
34eac1c Load application specific rake tasks in the application object
Carl Lerche authored
42 Dir["#{root}/vendor/plugins/*/**/tasks/**/*.rake"].sort.each { |ext| load ext }
43 Dir["#{root}/lib/tasks/**/*.rake"].sort.each { |ext| load ext }
530b8ff Have script/* and Rakefile use the application object
Carlhuda authored
44 task :environment do
45 $rails_rake_task = true
46 initialize!
47 end
48 end
49
897164d Conceptually unify instance & global initializers
Yehuda Katz + Carl Lerche authored
50 def call(env)
51 new.call(env)
e4d7e50 Moving more initializers into the application object
Carl Lerche authored
52 end
897164d Conceptually unify instance & global initializers
Yehuda Katz + Carl Lerche authored
53 end
6f6a589 Create the application object from config/environment.rb
Yehuda Katz + Carl Lerche authored
54
5f8e48c @josh Move route reloading into railties
josh authored
55 attr_reader :route_configuration_files
56
897164d Conceptually unify instance & global initializers
Yehuda Katz + Carl Lerche authored
57 def initialize
530b8ff Have script/* and Rakefile use the application object
Carlhuda authored
58 Rails.application ||= self
5f8e48c @josh Move route reloading into railties
josh authored
59
60 @route_configuration_files = []
61
82b9b15 Refactor plugins
Yehuda Katz + Carl Lerche authored
62 run_initializers(self)
897164d Conceptually unify instance & global initializers
Yehuda Katz + Carl Lerche authored
63 end
e4d7e50 Moving more initializers into the application object
Carl Lerche authored
64
897164d Conceptually unify instance & global initializers
Yehuda Katz + Carl Lerche authored
65 def config
66 self.class.config
67 end
6d6ae08 Start moving the initializers into the application object
Carl Lerche authored
68
530b8ff Have script/* and Rakefile use the application object
Carlhuda authored
69 def root
70 config.root
71 end
72
897164d Conceptually unify instance & global initializers
Yehuda Katz + Carl Lerche authored
73 alias configuration config
74
75 def middleware
76 config.middleware
77 end
78
79 def routes
80 ActionController::Routing::Routes
81 end
82
5f8e48c @josh Move route reloading into railties
josh authored
83 def routes_changed_at
84 routes_changed_at = nil
85
86 route_configuration_files.each do |config|
87 config_changed_at = File.stat(config).mtime
88
89 if routes_changed_at.nil? || config_changed_at > routes_changed_at
90 routes_changed_at = config_changed_at
91 end
92 end
93
94 routes_changed_at
95 end
96
97 def reload_routes!
98 routes.disable_clear_and_finalize = true
99
100 routes.clear!
101 route_configuration_files.each { |config| load(config) }
102 routes.finalize!
103
104 nil
105 ensure
106 routes.disable_clear_and_finalize = false
107 end
108
82b9b15 Refactor plugins
Yehuda Katz + Carl Lerche authored
109 def initializers
110 initializers = super
111 plugins.each { |p| initializers += p.initializers }
112 initializers
113 end
114
115 def plugins
116 @plugins ||= begin
1b27f5c Add the ability for plugins to set default configuration settings.
Carl Lerche authored
117 plugin_names = config.plugins || [:all]
118 Plugin.plugins.select { |p| plugin_names.include?(p.plugin_name) } +
82b9b15 Refactor plugins
Yehuda Katz + Carl Lerche authored
119 Plugin::Vendored.all(config.plugins || [:all], config.paths.vendor.plugins)
120 end
121 end
122
897164d Conceptually unify instance & global initializers
Yehuda Katz + Carl Lerche authored
123 def call(env)
124 @app ||= middleware.build(routes)
125 @app.call(env)
6d6ae08 Start moving the initializers into the application object
Carl Lerche authored
126 end
127
128 # Set the <tt>$LOAD_PATH</tt> based on the value of
129 # Configuration#load_paths. Duplicates are removed.
130 initializer :set_load_path do
131 config.paths.add_to_load_path
132 $LOAD_PATH.uniq!
133 end
134
e4d7e50 Moving more initializers into the application object
Carl Lerche authored
135 # Requires all frameworks specified by the Configuration#frameworks
136 # list. By default, all frameworks (Active Record, Active Support,
137 # Action Pack, Action Mailer, and Active Resource) are loaded.
138 initializer :require_frameworks do
3903499 Add support for bare ActiveSupport via config.active_support.bare
Carlhuda authored
139 require 'active_support/all' unless config.active_support.bare
140 config.frameworks.each { |framework| require(framework.to_s) }
e4d7e50 Moving more initializers into the application object
Carl Lerche authored
141 end
142
143 # Set the paths from which Rails will automatically load source files, and
144 # the load_once paths.
145 initializer :set_autoload_paths do
146 require 'active_support/dependencies'
147 ActiveSupport::Dependencies.load_paths = config.load_paths.uniq
148 ActiveSupport::Dependencies.load_once_paths = config.load_once_paths.uniq
149
150 extra = ActiveSupport::Dependencies.load_once_paths - ActiveSupport::Dependencies.load_paths
151 unless extra.empty?
152 abort <<-end_error
153 load_once_paths must be a subset of the load_paths.
154 Extra items in load_once_paths: #{extra * ','}
155 end_error
156 end
157
158 # Freeze the arrays so future modifications will fail rather than do nothing mysteriously
159 config.load_once_paths.freeze
160 end
161
feb04bf Move the ensure_tmp_directories_exist initializer to the application obj...
Carl Lerche authored
162 # Create tmp directories
163 initializer :ensure_tmp_directories_exist do
164 %w(cache pids sessions sockets).each do |dir_to_make|
bf9819f Have Rails.root be based off of config.ru
Carl Lerche authored
165 FileUtils.mkdir_p(File.join(config.root, 'tmp', dir_to_make))
ed77e84 Ported over more initializers
Carl Lerche authored
166 end
167 end
168
169 # Preload all frameworks specified by the Configuration#frameworks.
170 # Used by Passenger to ensure everything's loaded before forking and
171 # to avoid autoload race conditions in JRuby.
172 initializer :preload_frameworks do
173 if config.preload_frameworks
174 config.frameworks.each do |framework|
175 # String#classify and #constantize aren't available yet.
176 toplevel = Object.const_get(framework.to_s.gsub(/(?:^|_)(.)/) { $1.upcase })
177 toplevel.load_all! if toplevel.respond_to?(:load_all!)
178 end
feb04bf Move the ensure_tmp_directories_exist initializer to the application obj...
Carl Lerche authored
179 end
180 end
5c42157 Even more initializers ported over
Carl Lerche authored
181
182 # This initialization routine does nothing unless <tt>:active_record</tt>
183 # is one of the frameworks to load (Configuration#frameworks). If it is,
184 # this sets the database configuration from Configuration#database_configuration
185 # and then establishes the connection.
186 initializer :initialize_database do
187 if config.frameworks.include?(:active_record)
188 ActiveRecord::Base.configurations = config.database_configuration
189 ActiveRecord::Base.establish_connection
190 end
191 end
192
193 # Include middleware to serve up static assets
194 initializer :initialize_static_server do
195 if config.frameworks.include?(:action_controller) && config.serve_static_assets
196 config.middleware.use(ActionDispatch::Static, Rails.public_path)
197 end
198 end
199
200 initializer :initialize_middleware_stack do
201 if config.frameworks.include?(:action_controller)
b9d4ceb @josh Need to lazy realize middleware options so they can be modified in
josh authored
202 config.middleware.use(::Rack::Lock, :if => lambda { ActionController::Base.allow_concurrency })
203 config.middleware.use(ActionDispatch::ShowExceptions, lambda { ActionController::Base.consider_all_requests_local })
204 config.middleware.use(ActionDispatch::Callbacks, lambda { ActionController::Dispatcher.prepare_each_request })
5c42157 Even more initializers ported over
Carl Lerche authored
205 config.middleware.use(lambda { ActionController::Base.session_store }, lambda { ActionController::Base.session_options })
206 config.middleware.use(ActionDispatch::ParamsParser)
207 config.middleware.use(::Rack::MethodOverride)
208 config.middleware.use(::Rack::Head)
209 config.middleware.use(ActionDispatch::StringCoercion)
210 end
211 end
212
213 initializer :initialize_cache do
214 unless defined?(RAILS_CACHE)
215 silence_warnings { Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store(config.cache_store) }
216
217 if RAILS_CACHE.respond_to?(:middleware)
218 # Insert middleware to setup and teardown local cache for each request
219 config.middleware.insert_after(:"Rack::Lock", RAILS_CACHE.middleware)
220 end
221 end
222 end
223
224 initializer :initialize_framework_caches do
225 if config.frameworks.include?(:action_controller)
226 ActionController::Base.cache_store ||= RAILS_CACHE
227 end
228 end
229
230 initializer :initialize_logger do
231 # if the environment has explicitly defined a logger, use it
232 next if Rails.logger
233
234 unless logger = config.logger
235 begin
236 logger = ActiveSupport::BufferedLogger.new(config.log_path)
237 logger.level = ActiveSupport::BufferedLogger.const_get(config.log_level.to_s.upcase)
238 if RAILS_ENV == "production"
239 logger.auto_flushing = false
240 end
241 rescue StandardError => e
242 logger = ActiveSupport::BufferedLogger.new(STDERR)
243 logger.level = ActiveSupport::BufferedLogger::WARN
244 logger.warn(
245 "Rails Error: Unable to access log file. Please ensure that #{config.log_path} exists and is chmod 0666. " +
246 "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
247 )
248 end
249 end
250
251 # TODO: Why are we silencing warning here?
252 silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }
253 end
254
255 # Sets the logger for Active Record, Action Controller, and Action Mailer
256 # (but only for those frameworks that are to be loaded). If the framework's
257 # logger is already set, it is not changed, otherwise it is set to use
258 # RAILS_DEFAULT_LOGGER.
259 initializer :initialize_framework_logging do
260 for framework in ([ :active_record, :action_controller, :action_mailer ] & config.frameworks)
261 framework.to_s.camelize.constantize.const_get("Base").logger ||= Rails.logger
262 end
263
264 ActiveSupport::Dependencies.logger ||= Rails.logger
265 Rails.cache.logger ||= Rails.logger
266 end
267
268 # Sets the dependency loading mechanism based on the value of
269 # Configuration#cache_classes.
270 initializer :initialize_dependency_mechanism do
271 # TODO: Remove files from the $" and always use require
272 ActiveSupport::Dependencies.mechanism = config.cache_classes ? :require : :load
273 end
274
275 # Loads support for "whiny nil" (noisy warnings when methods are invoked
276 # on +nil+ values) if Configuration#whiny_nils is true.
277 initializer :initialize_whiny_nils do
278 require('active_support/whiny_nil') if config.whiny_nils
279 end
280
281 # Sets the default value for Time.zone, and turns on ActiveRecord::Base#time_zone_aware_attributes.
282 # If assigned value cannot be matched to a TimeZone, an exception will be raised.
283 initializer :initialize_time_zone do
284 if config.time_zone
36a9644 @jeremy Clarify date/time dependencies
jeremy authored
285 require 'active_support/core_ext/time/zones'
5c42157 Even more initializers ported over
Carl Lerche authored
286 zone_default = Time.__send__(:get_zone, config.time_zone)
287
288 unless zone_default
289 raise \
290 'Value assigned to config.time_zone not recognized.' +
291 'Run "rake -D time" for a list of tasks for finding appropriate time zone names.'
292 end
293
294 Time.zone_default = zone_default
295
296 if config.frameworks.include?(:active_record)
297 ActiveRecord::Base.time_zone_aware_attributes = true
298 ActiveRecord::Base.default_timezone = :utc
299 end
300 end
301 end
302
303 # Set the i18n configuration from config.i18n but special-case for the load_path which should be
304 # appended to what's already set instead of overwritten.
305 initializer :initialize_i18n do
306 config.i18n.each do |setting, value|
307 if setting == :load_path
308 I18n.load_path += value
309 else
310 I18n.send("#{setting}=", value)
311 end
312 end
313 end
992c2db Finish porting over the initializers to the app object and fix all the t...
Carl Lerche authored
314
315 # Initializes framework-specific settings for each of the loaded frameworks
316 # (Configuration#frameworks). The available settings map to the accessors
317 # on each of the corresponding Base classes.
318 initializer :initialize_framework_settings do
319 config.frameworks.each do |framework|
320 base_class = framework.to_s.camelize.constantize.const_get("Base")
321
322 config.send(framework).each do |setting, value|
323 base_class.send("#{setting}=", value)
324 end
325 end
326 end
327
328 # Sets +ActionController::Base#view_paths+ and +ActionMailer::Base#template_root+
329 # (but only for those frameworks that are to be loaded). If the framework's
330 # paths have already been set, it is not changed, otherwise it is
331 # set to use Configuration#view_path.
332 initializer :initialize_framework_views do
333 if config.frameworks.include?(:action_view)
334 view_path = ActionView::PathSet.type_cast(config.view_path, config.cache_classes)
335 ActionMailer::Base.template_root = view_path if config.frameworks.include?(:action_mailer) && ActionMailer::Base.view_paths.blank?
336 ActionController::Base.view_paths = view_path if config.frameworks.include?(:action_controller) && ActionController::Base.view_paths.blank?
337 end
338 end
339
340 initializer :initialize_metal do
341 # TODO: Make Rails and metal work without ActionController
342 if config.frameworks.include?(:action_controller)
343 Rails::Rack::Metal.requested_metals = config.metals
344
345 config.middleware.insert_before(
346 :"ActionDispatch::ParamsParser",
347 Rails::Rack::Metal, :if => Rails::Rack::Metal.metals.any?)
348 end
349 end
350
351 # # bail out if gems are missing - note that check_gem_dependencies will have
352 # # already called abort() unless $gems_rake_task is set
353 # return unless gems_dependencies_loaded
354 initializer :load_application_initializers do
d0f4d93 Remove some remnants of config.gem
Carl Lerche authored
355 Dir["#{configuration.root}/config/initializers/**/*.rb"].sort.each do |initializer|
356 load(initializer)
992c2db Finish porting over the initializers to the app object and fix all the t...
Carl Lerche authored
357 end
358 end
359
360 # Fires the user-supplied after_initialize block (Configuration#after_initialize)
361 initializer :after_initialize do
d0f4d93 Remove some remnants of config.gem
Carl Lerche authored
362 configuration.after_initialize_blocks.each do |block|
363 block.call
992c2db Finish porting over the initializers to the app object and fix all the t...
Carl Lerche authored
364 end
365 end
366
367 # # Setup database middleware after initializers have run
368 initializer :initialize_database_middleware do
369 if configuration.frameworks.include?(:active_record)
370 if configuration.frameworks.include?(:action_controller) && ActionController::Base.session_store &&
371 ActionController::Base.session_store.name == 'ActiveRecord::SessionStore'
372 configuration.middleware.insert_before :"ActiveRecord::SessionStore", ActiveRecord::ConnectionAdapters::ConnectionManagement
373 configuration.middleware.insert_before :"ActiveRecord::SessionStore", ActiveRecord::QueryCache
374 else
375 configuration.middleware.use ActiveRecord::ConnectionAdapters::ConnectionManagement
376 configuration.middleware.use ActiveRecord::QueryCache
377 end
378 end
379 end
380
381 # TODO: Make a DSL way to limit an initializer to a particular framework
382
383 # # Prepare dispatcher callbacks and run 'prepare' callbacks
384 initializer :prepare_dispatcher do
385 next unless configuration.frameworks.include?(:action_controller)
386 require 'rails/dispatcher' unless defined?(::Dispatcher)
387 Dispatcher.define_dispatcher_callbacks(configuration.cache_classes)
5f8e48c @josh Move route reloading into railties
josh authored
388
389 unless configuration.cache_classes
390 # Setup dev mode route reloading
391 routes_last_modified = routes_changed_at
392 reload_routes = lambda do
393 unless routes_changed_at == routes_last_modified
394 routes_last_modified = routes_changed_at
395 reload_routes!
396 end
397 end
f0bbc64 @josh Procs don't call themselves
josh authored
398 ActionDispatch::Callbacks.before_dispatch { |callbacks| reload_routes.call }
5f8e48c @josh Move route reloading into railties
josh authored
399 end
992c2db Finish porting over the initializers to the app object and fix all the t...
Carl Lerche authored
400 end
401
402 # Routing must be initialized after plugins to allow the former to extend the routes
403 # ---
404 # If Action Controller is not one of the loaded frameworks (Configuration#frameworks)
405 # this does nothing. Otherwise, it loads the routing definitions and sets up
406 # loading module used to lazily load controllers (Configuration#controller_paths).
407 initializer :initialize_routing do
408 next unless configuration.frameworks.include?(:action_controller)
5f8e48c @josh Move route reloading into railties
josh authored
409 route_configuration_files << configuration.routes_configuration_file
36624b2 @dhh Give the builtin controllers their own routes.rb now that the legacy cat...
dhh authored
410 route_configuration_files << configuration.builtin_routes_configuration_file
5f8e48c @josh Move route reloading into railties
josh authored
411 reload_routes!
992c2db Finish porting over the initializers to the app object and fix all the t...
Carl Lerche authored
412 end
413 #
414 # # Observers are loaded after plugins in case Observers or observed models are modified by plugins.
415 initializer :load_observers do
d0f4d93 Remove some remnants of config.gem
Carl Lerche authored
416 if configuration.frameworks.include?(:active_record)
992c2db Finish porting over the initializers to the app object and fix all the t...
Carl Lerche authored
417 ActiveRecord::Base.instantiate_observers
418 end
419 end
420
421 # Eager load application classes
422 initializer :load_application_classes do
423 next if $rails_rake_task
424
425 if configuration.cache_classes
426 configuration.eager_load_paths.each do |load_path|
427 matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/
428 Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
429 require_dependency file.sub(matcher, '\1')
430 end
431 end
432 end
433 end
434
435 # Disable dependency loading during request cycle
436 initializer :disable_dependency_loading do
437 if configuration.cache_classes && !configuration.dependency_loading
438 ActiveSupport::Dependencies.unhook!
439 end
440 end
441
2d7abe2 @josevalim Renamed Orchestra to Notifications once again [#3321 state:resolved]
josevalim authored
442 # For each framework, search for instrument file with Notifications hooks.
aeaabc6 @josevalim Configure Orchestra on initialization.
josevalim authored
443 #
2d7abe2 @josevalim Renamed Orchestra to Notifications once again [#3321 state:resolved]
josevalim authored
444 initializer :load_notifications_hooks do
aeaabc6 @josevalim Configure Orchestra on initialization.
josevalim authored
445 config.frameworks.each do |framework|
446 begin
2d7abe2 @josevalim Renamed Orchestra to Notifications once again [#3321 state:resolved]
josevalim authored
447 require "#{framework}/notifications"
aeaabc6 @josevalim Configure Orchestra on initialization.
josevalim authored
448 rescue LoadError => e
449 end
450 end
451 end
accd9b4 @josh Restore "Start Rails::Application object
josh authored
452 end
453 end
Something went wrong with that request. Please try again.