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
This commit is contained in:
David Heinemeier Hansson 2004-11-30 17:19:01 +00:00
parent 38e5fe97be
commit 5b38d85571
5 changed files with 47 additions and 27 deletions

View File

@ -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

View File

@ -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:

View File

@ -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")

View File

@ -1,5 +1,6 @@
ENV["RAILS_ENV"] ||= "test"
require File.dirname(__FILE__) + "/../config/environment"
require 'abstract_application'
require 'test/unit'
require 'active_record/fixtures'

View File

@ -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
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
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