aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib/rails/application.rb
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2011-12-12 22:51:33 +0100
committerJosé Valim <jose.valim@gmail.com>2011-12-12 22:54:04 +0100
commitfa1d9a884c0d5b70c97442e3360ac98ca5fa4340 (patch)
treee39e017a9de2936a87f3b9ecf1d14b6febd0a8f1 /railties/lib/rails/application.rb
parent62cda03fa824ce1e1fc92aaee0367c29ade6a504 (diff)
downloadrails-fa1d9a884c0d5b70c97442e3360ac98ca5fa4340.tar.gz
rails-fa1d9a884c0d5b70c97442e3360ac98ca5fa4340.tar.bz2
rails-fa1d9a884c0d5b70c97442e3360ac98ca5fa4340.zip
Speed up development by only reloading classes if dependencies files changed.
This can be turned off by setting `config.reload_classes_only_on_change` to false. Extensions like Active Record should add their respective files like db/schema.rb and db/structure.sql to `config.watchable_files` if they want their changes to affect classes reloading. Thanks to https://github.com/paneq/active_reload and Pastorino for the inspiration. <3
Diffstat (limited to 'railties/lib/rails/application.rb')
-rw-r--r--railties/lib/rails/application.rb40
1 files changed, 38 insertions, 2 deletions
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index acbfd7078b..0b8eac8a8b 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -71,12 +71,14 @@ module Rails
attr_accessor :assets, :sandbox
alias_method :sandbox?, :sandbox
+ attr_reader :reloaders
delegate :default_url_options, :default_url_options=, :to => :routes
def initialize
super
@initialized = false
+ @reloaders = []
end
# This method is called just after an application inherits from Rails::Application,
@@ -119,6 +121,7 @@ module Rails
reloader = routes_reloader
hook = lambda { reloader.execute_if_updated }
hook.call
+ self.reloaders << reloader
ActionDispatch::Reloader.to_prepare(&hook)
end
@@ -126,10 +129,35 @@ module Rails
# A plugin may override this if they desire to provide a more exquisite app reloading.
# :api: plugin
def set_dependencies_hook
- ActionDispatch::Reloader.to_cleanup do
+ callback = lambda do
ActiveSupport::DescendantsTracker.clear
ActiveSupport::Dependencies.clear
end
+
+ if config.reload_classes_only_on_change
+ reloader = ActiveSupport::FileUpdateChecker.new(watchable_args, true, &callback)
+ self.reloaders << reloader
+ # We need to set a to_prepare callback regardless of the reloader result, i.e.
+ # models should be reloaded if any of the reloaders (i18n, routes) were updated.
+ ActionDispatch::Reloader.to_prepare(:prepend => true, &callback)
+ else
+ ActionDispatch::Reloader.to_cleanup(&callback)
+ end
+ end
+
+ # Returns an array of file paths appended with a hash of directories-extensions
+ # suitable for ActiveSupport::FileUpdateChecker API.
+ def watchable_args
+ files = []
+ files.concat config.watchable_files
+
+ dirs = {}
+ dirs.merge! config.watchable_dirs
+ ActiveSupport::Dependencies.autoload_paths.each do |path|
+ dirs[path.to_s] = [:rb]
+ end
+
+ files << dirs
end
# Initialize the application passing the given group. By default, the
@@ -223,6 +251,10 @@ module Rails
alias :build_middleware_stack :app
+ def reload_dependencies?
+ config.reload_classes_only_on_change != true || reloaders.map(&:updated?).any?
+ end
+
def default_middleware_stack
ActionDispatch::MiddlewareStack.new.tap do |middleware|
if rack_cache = config.action_controller.perform_caching && config.action_dispatch.rack_cache
@@ -252,7 +284,11 @@ module Rails
middleware.use ::Rack::Sendfile, config.action_dispatch.x_sendfile_header
end
- middleware.use ::ActionDispatch::Reloader unless config.cache_classes
+ unless config.cache_classes
+ app = self
+ middleware.use ::ActionDispatch::Reloader, lambda { app.reload_dependencies? }
+ end
+
middleware.use ::ActionDispatch::Callbacks
middleware.use ::ActionDispatch::Cookies