From 5b38d8557122723aa7c11c28d4c2c93464982766 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Tue, 30 Nov 2004 17:19:01 +0000 Subject: AbstractApplicationController and the individual controllers are now completely reloaded on each request if "reload_dependencies" is set to true. This makes it possible to REMOVE methods and constants and have the changes reflected. Beaware that this is still not possible for models, though. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@31 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- railties/dispatches/dispatch.rb | 2 +- railties/environments/shared.rb | 13 ++++----- railties/environments/shared_for_gem.rb | 10 +++---- railties/helpers/test_helper.rb | 1 + railties/lib/dispatcher.rb | 48 ++++++++++++++++++++++++--------- 5 files changed, 47 insertions(+), 27 deletions(-) diff --git a/railties/dispatches/dispatch.rb b/railties/dispatches/dispatch.rb index eb2c95e813..6ac11bbd59 100755 --- a/railties/dispatches/dispatch.rb +++ b/railties/dispatches/dispatch.rb @@ -6,5 +6,5 @@ require File.dirname(__FILE__) + "/../config/environment" # "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired require "dispatcher" -ADDITIONAL_LOAD_PATHS.flatten.each { |dir| $:.unshift "#{RAILS_ROOT}/#{dir}" } +ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } Dispatcher.dispatch \ No newline at end of file diff --git a/railties/environments/shared.rb b/railties/environments/shared.rb index 78628341e8..0e30f1368b 100644 --- a/railties/environments/shared.rb +++ b/railties/environments/shared.rb @@ -6,14 +6,14 @@ RAILS_ENV = ENV['RAILS_ENV'] || 'development' ADDITIONAL_LOAD_PATHS = ["#{RAILS_ROOT}/test/mocks/#{RAILS_ENV}"] # Then model subdirectories. -ADDITIONAL_LOAD_PATHS.concat(Dir["#{RAILS_ROOT}/app/models/[a-z]*"]) +ADDITIONAL_LOAD_PATHS.concat(Dir["#{RAILS_ROOT}/app/models/[_a-z]*"]) # Followed by the standard includes. ADDITIONAL_LOAD_PATHS.concat %w( + app app/models app/controllers app/helpers - app config lib vendor @@ -25,9 +25,7 @@ ADDITIONAL_LOAD_PATHS.concat %w( ).map { |dir| "#{RAILS_ROOT}/#{dir}" } # Prepend to $LOAD_PATH -ADDITIONAL_LOAD_PATHS.reverse.each do |dir| - $:.unshift(dir) if File.directory?(dir) -end +ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } # Require Rails libraries. @@ -37,12 +35,10 @@ require 'action_mailer' # Environment-specific configuration. +ActionController::Base.require_or_load "environments/#{RAILS_ENV}" ActiveRecord::Base.configurations = YAML::load(File.open("#{RAILS_ROOT}/config/database.yml")) ActiveRecord::Base.establish_connection -ActionController::Base.require_or_load 'abstract_application' -ActionController::Base.require_or_load "environments/#{RAILS_ENV}" - # Configure defaults if the included environment did not. RAILS_DEFAULT_LOGGER = Logger.new("#{RAILS_ROOT}/log/#{RAILS_ENV}.log") @@ -53,4 +49,5 @@ end klass.template_root ||= "#{RAILS_ROOT}/app/views/" end + # Include your app's configuration here: diff --git a/railties/environments/shared_for_gem.rb b/railties/environments/shared_for_gem.rb index dde6a01db7..0316522258 100644 --- a/railties/environments/shared_for_gem.rb +++ b/railties/environments/shared_for_gem.rb @@ -6,10 +6,11 @@ RAILS_ENV = ENV['RAILS_ENV'] || 'development' ADDITIONAL_LOAD_PATHS = ["#{RAILS_ROOT}/test/mocks/#{RAILS_ENV}"] # Then model subdirectories. -ADDITIONAL_LOAD_PATHS.concat(Dir["#{RAILS_ROOT}/app/models/[a-z]*"]) +ADDITIONAL_LOAD_PATHS.concat(Dir["#{RAILS_ROOT}/app/models/[_a-z]*"]) # Followed by the standard includes. ADDITIONAL_LOAD_PATHS.concat %w( + app app/models app/controllers app/helpers @@ -19,9 +20,7 @@ ADDITIONAL_LOAD_PATHS.concat %w( ).map { |dir| "#{RAILS_ROOT}/#{dir}" } # Prepend to $LOAD_PATH -ADDITIONAL_LOAD_PATHS.reverse.each do |dir| - $:.unshift(dir) if File.directory?(dir) -end +ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } # Require Rails gems. @@ -33,11 +32,10 @@ require_gem 'rails' # Environment-specific configuration. +ActionController::Base.require_or_load "environments/#{RAILS_ENV}" ActiveRecord::Base.configurations = YAML::load(File.open("#{RAILS_ROOT}/config/database.yml")) ActiveRecord::Base.establish_connection -ActionController::Base.require_or_load 'abstract_application' -ActionController::Base.require_or_load "environments/#{RAILS_ENV}" # Configure defaults if the included environment did not. RAILS_DEFAULT_LOGGER = Logger.new("#{RAILS_ROOT}/log/#{RAILS_ENV}.log") diff --git a/railties/helpers/test_helper.rb b/railties/helpers/test_helper.rb index d348f26517..4d683e3500 100644 --- a/railties/helpers/test_helper.rb +++ b/railties/helpers/test_helper.rb @@ -1,5 +1,6 @@ ENV["RAILS_ENV"] ||= "test" require File.dirname(__FILE__) + "/../config/environment" +require 'abstract_application' require 'test/unit' require 'active_record/fixtures' diff --git a/railties/lib/dispatcher.rb b/railties/lib/dispatcher.rb index aa7ae98edd..c765a79443 100644 --- a/railties/lib/dispatcher.rb +++ b/railties/lib/dispatcher.rb @@ -28,19 +28,14 @@ class Dispatcher begin request = ActionController::CgiRequest.new(cgi, session_options) response = ActionController::CgiResponse.new(cgi) + + controller_name, module_name = controller_name(request.parameters), module_name(request.parameters) - controller_name = request.parameters["controller"].gsub(/[^_a-zA-Z0-9]/, "").untaint + ActionController::Base.require_or_load("abstract_application") + ActionController::Base.require_or_load(controller_path(controller_name, module_name)) - if module_name = request.parameters["module"] - Module.new do - ActionController::Base.require_or_load "#{module_name}/#{Inflector.underscore(controller_name)}_controller" - Object.const_get("#{Inflector.camelize(controller_name)}Controller").process(request, response).out - end - else - ActionController::Base.require_or_load "#{Inflector.underscore(controller_name)}_controller" - Object.const_get("#{Inflector.camelize(controller_name)}Controller").process(request, response).out - end - rescue Exception => e + controller_class(controller_name).process(request, response).out + rescue Object => e begin ActionController::Base.logger.info "\n\nException throw during dispatch: #{e.message}\n#{e.backtrace.join("\n")}" rescue Exception @@ -50,6 +45,35 @@ class Dispatcher if error_page then cgi.out{ IO.readlines(error_page) } else raise e end ensure ActiveRecord::Base.reset_associations_loaded + + if ActionController::Base.reload_dependencies + Object.send(:remove_const, "AbstractApplicationController") + Object.send(:remove_const, controller_class_name(controller_name)) if Object.const_defined?(controller_class_name(controller_name)) + end + end + end + + def self.controller_path(controller_name, module_name = nil) + if module_name + "#{module_name}/#{Inflector.underscore(controller_name)}_controller" + else + "#{Inflector.underscore(controller_name)}_controller" end end -end + + def self.controller_class(controller_name) + Object.const_get(controller_class_name(controller_name)) + end + + def self.controller_class_name(controller_name) + "#{Inflector.camelize(controller_name)}Controller" + end + + def self.controller_name(parameters) + parameters["controller"].gsub(/[^_a-zA-Z0-9]/, "").untaint + end + + def self.module_name(parameters) + parameters["module"].gsub(/[^_a-zA-Z0-9]/, "").untaint if parameters["module"] + end +end \ No newline at end of file -- cgit v1.2.3