Properly reload routes defined in class definition
Sometimes it's easier to define routes inside Engine or Application class definition (e.g. one file applications). The problem with such case is that if there is a plugin that has config/routes.rb file, it will trigger routes reload on application. Since routes definition for application is not in config/routes.rb file routes_reloader will fail to reload application's routes properly. With this commit you can pass routes definition as a block to routes method, which will allow to properly reload it: class MyApp::Application < Rails::Application routes do resources :users end end
This commit is contained in:
parent
22b11a41cc
commit
ec5d846ac6
|
@ -1,6 +1,7 @@
|
|||
require 'rack/mount'
|
||||
require 'forwardable'
|
||||
require 'active_support/core_ext/object/to_query'
|
||||
require 'active_support/core_ext/hash/slice'
|
||||
|
||||
module ActionDispatch
|
||||
module Routing
|
||||
|
|
|
@ -85,14 +85,25 @@ module Rails
|
|||
end
|
||||
|
||||
def reload_routes!
|
||||
routes_to_reload.each do |_routes, draw_block|
|
||||
_routes = self.routes
|
||||
_routes.disable_clear_and_finalize = true
|
||||
_routes.clear!
|
||||
_routes.draw(&draw_block) if draw_block
|
||||
end
|
||||
routes_reloader.paths.each { |path| load(path) }
|
||||
routes_to_reload.each do |_routes, draw_block|
|
||||
ActiveSupport.on_load(:action_controller) { _routes.finalize! }
|
||||
end
|
||||
ensure
|
||||
routes_to_reload.each do |_routes, draw_block|
|
||||
_routes.disable_clear_and_finalize = false
|
||||
end
|
||||
end
|
||||
|
||||
def routes_to_reload
|
||||
@routes_to_reload ||= {}
|
||||
end
|
||||
|
||||
def initialize!
|
||||
raise "Application has been already initialized." if @initialized
|
||||
|
|
|
@ -399,8 +399,10 @@ module Rails
|
|||
}
|
||||
end
|
||||
|
||||
def routes
|
||||
def routes(&block)
|
||||
@routes ||= ActionDispatch::Routing::RouteSet.new
|
||||
self.routes_draw_block = block if block_given?
|
||||
@routes
|
||||
end
|
||||
|
||||
def initializers
|
||||
|
@ -447,6 +449,7 @@ module Rails
|
|||
end
|
||||
|
||||
initializer :add_routing_paths do |app|
|
||||
app.routes_to_reload[self.routes] = routes_draw_block
|
||||
paths.config.routes.to_a.each do |route|
|
||||
app.routes_reloader.paths.unshift(route) if File.exists?(route)
|
||||
end
|
||||
|
@ -499,6 +502,8 @@ module Rails
|
|||
end
|
||||
|
||||
protected
|
||||
attr_accessor :routes_draw_block
|
||||
|
||||
def find_root_with_flag(flag, default=nil)
|
||||
root_path = self.class.called_from
|
||||
|
||||
|
|
|
@ -663,5 +663,45 @@ module RailtiesTest
|
|||
|
||||
assert_equal AppTemplate._railtie, AppTemplate::Engine
|
||||
end
|
||||
|
||||
test "properly reload routes" do
|
||||
# when routes are inside application class definition
|
||||
# they should not be reloaded when engine's routes
|
||||
# file has changed
|
||||
add_to_config <<-RUBY
|
||||
routes do
|
||||
mount lambda{|env| [200, {}, ["foo"]]} => "/foo"
|
||||
mount Bukkits::Engine => "/bukkits"
|
||||
end
|
||||
RUBY
|
||||
|
||||
FileUtils.rm(File.join(app_path, "config/routes.rb"))
|
||||
|
||||
@plugin.write "config/routes.rb", <<-RUBY
|
||||
Bukkits::Engine.routes.draw do
|
||||
mount lambda{|env| [200, {}, ["bar"]]} => "/bar"
|
||||
end
|
||||
RUBY
|
||||
|
||||
@plugin.write "lib/bukkits.rb", <<-RUBY
|
||||
module Bukkits
|
||||
class Engine < ::Rails::Engine
|
||||
namespace(Bukkits)
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
require 'rack/test'
|
||||
extend Rack::Test::Methods
|
||||
|
||||
boot_rails
|
||||
|
||||
require "#{rails_root}/config/environment"
|
||||
get "/foo"
|
||||
assert_equal "foo", last_response.body
|
||||
|
||||
get "/bukkits/bar"
|
||||
assert_equal "bar", last_response.body
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue