aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_controller/routing/route_set.rb54
-rw-r--r--actionpack/test/controller/routing_test.rb29
-rw-r--r--railties/CHANGELOG2
-rw-r--r--railties/lib/initializer.rb9
-rw-r--r--railties/lib/rails/plugin.rb23
-rw-r--r--railties/lib/rails/plugin/loader.rb17
-rw-r--r--railties/test/fixtures/plugins/engines/engine/app/controllers/engine_controller.rb2
-rw-r--r--railties/test/fixtures/plugins/engines/engine/app/models/engine_model.rb2
-rw-r--r--railties/test/fixtures/plugins/engines/engine/config/routes.rb3
-rw-r--r--railties/test/fixtures/plugins/engines/engine/init.rb3
-rw-r--r--railties/test/initializer_test.rb1
-rw-r--r--railties/test/plugin_locator_test.rb2
12 files changed, 125 insertions, 22 deletions
diff --git a/actionpack/lib/action_controller/routing/route_set.rb b/actionpack/lib/action_controller/routing/route_set.rb
index 89cdf9d0f5..a9690d1807 100644
--- a/actionpack/lib/action_controller/routing/route_set.rb
+++ b/actionpack/lib/action_controller/routing/route_set.rb
@@ -200,9 +200,11 @@ module ActionController
end
end
- attr_accessor :routes, :named_routes, :configuration_file
+ attr_accessor :routes, :named_routes, :configuration_files
def initialize
+ self.configuration_files = []
+
self.routes = []
self.named_routes = NamedRouteCollection.new
@@ -216,7 +218,6 @@ module ActionController
end
def draw
- clear!
yield Mapper.new(self)
install_helpers
end
@@ -240,8 +241,22 @@ module ActionController
routes.empty?
end
+ def add_configuration_file(path)
+ self.configuration_files << path
+ end
+
+ # Deprecated accessor
+ def configuration_file=(path)
+ add_configuration_file(path)
+ end
+
+ # Deprecated accessor
+ def configuration_file
+ configuration_files
+ end
+
def load!
- Routing.use_controllers! nil # Clear the controller cache so we may discover new ones
+ Routing.use_controllers!(nil) # Clear the controller cache so we may discover new ones
clear!
load_routes!
end
@@ -250,24 +265,39 @@ module ActionController
alias reload! load!
def reload
- if @routes_last_modified && configuration_file
- mtime = File.stat(configuration_file).mtime
- # if it hasn't been changed, then just return
- return if mtime == @routes_last_modified
- # if it has changed then record the new time and fall to the load! below
- @routes_last_modified = mtime
+ if configuration_files.any? && @routes_last_modified
+ if routes_changed_at == @routes_last_modified
+ return # routes didn't change, don't reload
+ else
+ @routes_last_modified = routes_changed_at
+ end
end
+
load!
end
def load_routes!
- if configuration_file
- load configuration_file
- @routes_last_modified = File.stat(configuration_file).mtime
+ if configuration_files.any?
+ configuration_files.each { |config| load(config) }
+ @routes_last_modified = routes_changed_at
else
add_route ":controller/:action/:id"
end
end
+
+ def routes_changed_at
+ routes_changed_at = nil
+
+ configuration_files.each do |config|
+ config_changed_at = File.stat(config).mtime
+
+ if routes_changed_at.nil? || config_changed_at > routes_changed_at
+ routes_changed_at = config_changed_at
+ end
+ end
+
+ routes_changed_at
+ end
def add_route(path, options = {})
route = builder.build(path, options)
diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb
index d62c7a1743..d5b6bd6b2a 100644
--- a/actionpack/test/controller/routing_test.rb
+++ b/actionpack/test/controller/routing_test.rb
@@ -747,12 +747,16 @@ uses_mocha 'LegacyRouteSet, Route, RouteSet and RouteLoading' do
ActionController::Base.optimise_named_routes = true
@rs = ::ActionController::Routing::RouteSet.new
- @rs.draw {|m| m.connect ':controller/:action/:id' }
ActionController::Routing.use_controllers! %w(content admin/user admin/news_feed)
end
+
+ def teardown
+ @rs.clear!
+ end
def test_default_setup
+ @rs.draw {|m| m.connect ':controller/:action/:id' }
assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/content"))
assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/content/list"))
assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/content/show/10"))
@@ -769,6 +773,7 @@ uses_mocha 'LegacyRouteSet, Route, RouteSet and RouteLoading' do
end
def test_ignores_leading_slash
+ @rs.clear!
@rs.draw {|m| m.connect '/:controller/:action/:id'}
test_default_setup
end
@@ -1002,6 +1007,8 @@ uses_mocha 'LegacyRouteSet, Route, RouteSet and RouteLoading' do
end
def test_changing_controller
+ @rs.draw {|m| m.connect ':controller/:action/:id' }
+
assert_equal '/admin/stuff/show/10', rs.generate(
{:controller => 'stuff', :action => 'show', :id => 10},
{:controller => 'admin/user', :action => 'index'}
@@ -1155,10 +1162,12 @@ uses_mocha 'LegacyRouteSet, Route, RouteSet and RouteLoading' do
end
def test_action_expiry
+ @rs.draw {|m| m.connect ':controller/:action/:id' }
assert_equal '/content', rs.generate({:controller => 'content'}, {:controller => 'content', :action => 'show'})
end
def test_recognition_with_uppercase_controller_name
+ @rs.draw {|m| m.connect ':controller/:action/:id' }
assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/Content"))
assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/ConTent/list"))
assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/CONTENT/show/10"))
@@ -2399,13 +2408,13 @@ uses_mocha 'LegacyRouteSet, Route, RouteSet and RouteLoading' do
def setup
routes.instance_variable_set '@routes_last_modified', nil
silence_warnings { Object.const_set :RAILS_ROOT, '.' }
- ActionController::Routing::Routes.configuration_file = File.join(RAILS_ROOT, 'config', 'routes.rb')
+ routes.add_configuration_file(File.join(RAILS_ROOT, 'config', 'routes.rb'))
@stat = stub_everything
end
def teardown
- ActionController::Routing::Routes.configuration_file = nil
+ ActionController::Routing::Routes.configuration_files.clear
Object.send :remove_const, :RAILS_ROOT
end
@@ -2448,12 +2457,24 @@ uses_mocha 'LegacyRouteSet, Route, RouteSet and RouteLoading' do
end
def test_load_with_configuration
- routes.configuration_file = "foobarbaz"
+ routes.configuration_files.clear
+ routes.add_configuration_file("foobarbaz")
File.expects(:stat).returns(@stat)
routes.expects(:load).with("foobarbaz")
routes.reload
end
+
+ def test_load_multiple_configurations
+ routes.add_configuration_file("engines.rb")
+
+ File.expects(:stat).at_least_once.returns(@stat)
+
+ routes.expects(:load).with('./config/routes.rb')
+ routes.expects(:load).with('engines.rb')
+
+ routes.reload
+ end
private
def routes
diff --git a/railties/CHANGELOG b/railties/CHANGELOG
index 6cd57e295b..5324a7c73b 100644
--- a/railties/CHANGELOG
+++ b/railties/CHANGELOG
@@ -1,5 +1,7 @@
*2.3.0 [Edge]*
+* Added that config/routes.rb files in engine plugins are automatically loaded (and reloaded when they change in dev mode) [DHH]
+
* Added app/[models|controllers|helpers] to the load path for plugins that has an app directory (go engines ;)) [DHH]
* Add config.preload_frameworks to load all frameworks at startup. Default to false so Rails autoloads itself as it's used. Turn this on for Passenger and JRuby. Also turned on by config.threadsafe! [Jeremy Kemper]
diff --git a/railties/lib/initializer.rb b/railties/lib/initializer.rb
index 038288dc88..b0abf3379c 100644
--- a/railties/lib/initializer.rb
+++ b/railties/lib/initializer.rb
@@ -486,8 +486,13 @@ Run `rake gems:install` to install the missing gems.
# loading module used to lazily load controllers (Configuration#controller_paths).
def initialize_routing
return unless configuration.frameworks.include?(:action_controller)
- ActionController::Routing.controller_paths = configuration.controller_paths
- ActionController::Routing::Routes.configuration_file = configuration.routes_configuration_file
+
+ ActionController::Routing.controller_paths = configuration.controller_paths + plugin_loader.controller_paths
+
+ ([ configuration.routes_configuration_file ] + plugin_loader.routing_files).each do |routing_file|
+ ActionController::Routing::Routes.add_configuration_file(routing_file)
+ end
+
ActionController::Routing::Routes.reload
end
diff --git a/railties/lib/rails/plugin.rb b/railties/lib/rails/plugin.rb
index 3b9e7dec2d..2b1e877e2b 100644
--- a/railties/lib/rails/plugin.rb
+++ b/railties/lib/rails/plugin.rb
@@ -40,7 +40,7 @@ module Rails
load_paths << app_paths if has_app_directory?
end.flatten
end
-
+
# Evaluates a plugin's init.rb file.
def load(initializer)
return if loaded?
@@ -60,7 +60,26 @@ module Rails
def about
@about ||= load_about_information
end
+
+ # Engines are plugins with an app/ directory.
+ def engine?
+ has_app_directory?
+ end
+ # Returns true if the engine ships with a routing file
+ def routed?
+ File.exist?(routing_file)
+ end
+
+ def controller_path
+ File.join(directory, 'app', 'controllers')
+ end
+
+ def routing_file
+ File.join(directory, 'config', 'routes.rb')
+ end
+
+
private
def load_about_information
about_yml_path = File.join(@directory, "about.yml")
@@ -82,7 +101,7 @@ module Rails
File.join(directory, 'app', 'helpers')
]
end
-
+
def lib_path
File.join(directory, 'lib')
end
diff --git a/railties/lib/rails/plugin/loader.rb b/railties/lib/rails/plugin/loader.rb
index 8d7eac53c5..ba3f67d1d0 100644
--- a/railties/lib/rails/plugin/loader.rb
+++ b/railties/lib/rails/plugin/loader.rb
@@ -22,6 +22,11 @@ module Rails
@plugins ||= all_plugins.select { |plugin| should_load?(plugin) }.sort { |p1, p2| order_plugins(p1, p2) }
end
+ # Returns the plugins that are in engine-form (have an app/ directory)
+ def engines
+ @engines ||= plugins.select(&:engine?)
+ end
+
# Returns all the plugins that could be found by the current locators.
def all_plugins
@all_plugins ||= locate_plugins
@@ -56,7 +61,17 @@ module Rails
end
$LOAD_PATH.uniq!
- end
+ end
+
+ # Returns an array of all the controller paths found inside engine-type plugins.
+ def controller_paths
+ engines.collect(&:controller_path)
+ end
+
+ def routing_files
+ engines.select(&:routed?).collect(&:routing_file)
+ end
+
protected
diff --git a/railties/test/fixtures/plugins/engines/engine/app/controllers/engine_controller.rb b/railties/test/fixtures/plugins/engines/engine/app/controllers/engine_controller.rb
new file mode 100644
index 0000000000..f08373de40
--- /dev/null
+++ b/railties/test/fixtures/plugins/engines/engine/app/controllers/engine_controller.rb
@@ -0,0 +1,2 @@
+class EngineController < ActionController::Base
+end \ No newline at end of file
diff --git a/railties/test/fixtures/plugins/engines/engine/app/models/engine_model.rb b/railties/test/fixtures/plugins/engines/engine/app/models/engine_model.rb
new file mode 100644
index 0000000000..e265712185
--- /dev/null
+++ b/railties/test/fixtures/plugins/engines/engine/app/models/engine_model.rb
@@ -0,0 +1,2 @@
+class EngineModel
+end \ No newline at end of file
diff --git a/railties/test/fixtures/plugins/engines/engine/config/routes.rb b/railties/test/fixtures/plugins/engines/engine/config/routes.rb
new file mode 100644
index 0000000000..cca8d1b146
--- /dev/null
+++ b/railties/test/fixtures/plugins/engines/engine/config/routes.rb
@@ -0,0 +1,3 @@
+ActionController::Routing::Routes.draw do |map|
+ map.connect '/engine', :controller => "engine"
+end
diff --git a/railties/test/fixtures/plugins/engines/engine/init.rb b/railties/test/fixtures/plugins/engines/engine/init.rb
new file mode 100644
index 0000000000..f4b00c0fa4
--- /dev/null
+++ b/railties/test/fixtures/plugins/engines/engine/init.rb
@@ -0,0 +1,3 @@
+# My app/models dir must be in the load path.
+require 'engine_model'
+raise 'missing model from my app/models dir' unless defined?(EngineModel)
diff --git a/railties/test/initializer_test.rb b/railties/test/initializer_test.rb
index 88c267b58e..2104412c54 100644
--- a/railties/test/initializer_test.rb
+++ b/railties/test/initializer_test.rb
@@ -252,6 +252,7 @@ uses_mocha "Initializer plugin loading tests" do
assert $LOAD_PATH.include?(File.join(plugin_fixture_path('default/acts/acts_as_chunky_bacon'), 'lib'))
end
+
private
def load_plugins!
diff --git a/railties/test/plugin_locator_test.rb b/railties/test/plugin_locator_test.rb
index 363fa27f15..5a8c651e5a 100644
--- a/railties/test/plugin_locator_test.rb
+++ b/railties/test/plugin_locator_test.rb
@@ -47,7 +47,7 @@ uses_mocha "Plugin Locator Tests" do
end
def test_should_return_all_plugins_found_under_the_set_plugin_paths
- assert_equal ["a", "acts_as_chunky_bacon", "gemlike", "plugin_with_no_lib_dir", "stubby"].sort, @locator.plugins.map(&:name).sort
+ assert_equal ["a", "acts_as_chunky_bacon", "engine", "gemlike", "plugin_with_no_lib_dir", "stubby"].sort, @locator.plugins.map(&:name).sort
end
def test_should_find_plugins_only_under_the_plugin_paths_set_in_configuration